1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * CAN bus driver for the Freescale MPC5xxx embedded CPU. |
4 | * |
5 | * Copyright (C) 2004-2005 Andrey Volkov <avolkov@varma-el.com>, |
6 | * Varma Electronics Oy |
7 | * Copyright (C) 2008-2009 Wolfgang Grandegger <wg@grandegger.com> |
8 | * Copyright (C) 2009 Wolfram Sang, Pengutronix <kernel@pengutronix.de> |
9 | */ |
10 | |
11 | #include <linux/kernel.h> |
12 | #include <linux/module.h> |
13 | #include <linux/interrupt.h> |
14 | #include <linux/platform_device.h> |
15 | #include <linux/property.h> |
16 | #include <linux/netdevice.h> |
17 | #include <linux/can/dev.h> |
18 | #include <linux/of.h> |
19 | #include <linux/of_address.h> |
20 | #include <linux/of_irq.h> |
21 | #include <linux/of_platform.h> |
22 | #include <sysdev/fsl_soc.h> |
23 | #include <linux/clk.h> |
24 | #include <linux/io.h> |
25 | #include <asm/mpc52xx.h> |
26 | |
27 | #include "mscan.h" |
28 | |
29 | #define DRV_NAME "mpc5xxx_can" |
30 | |
31 | struct mpc5xxx_can_data { |
32 | unsigned int type; |
33 | u32 (*get_clock)(struct platform_device *ofdev, const char *clock_name, |
34 | int *mscan_clksrc); |
35 | void (*put_clock)(struct platform_device *ofdev); |
36 | }; |
37 | |
38 | #ifdef CONFIG_PPC_MPC52xx |
39 | static const struct of_device_id mpc52xx_cdm_ids[] = { |
40 | { .compatible = "fsl,mpc5200-cdm" , }, |
41 | {} |
42 | }; |
43 | |
44 | static u32 mpc52xx_can_get_clock(struct platform_device *ofdev, |
45 | const char *clock_name, int *mscan_clksrc) |
46 | { |
47 | unsigned int pvr; |
48 | struct mpc52xx_cdm __iomem *cdm; |
49 | struct device_node *np_cdm; |
50 | unsigned int freq; |
51 | u32 val; |
52 | |
53 | pvr = mfspr(SPRN_PVR); |
54 | |
55 | /* |
56 | * Either the oscillator clock (SYS_XTAL_IN) or the IP bus clock |
57 | * (IP_CLK) can be selected as MSCAN clock source. According to |
58 | * the MPC5200 user's manual, the oscillator clock is the better |
59 | * choice as it has less jitter. For this reason, it is selected |
60 | * by default. Unfortunately, it can not be selected for the old |
61 | * MPC5200 Rev. A chips due to a hardware bug (check errata). |
62 | */ |
63 | if (clock_name && strcmp(clock_name, "ip" ) == 0) |
64 | *mscan_clksrc = MSCAN_CLKSRC_BUS; |
65 | else |
66 | *mscan_clksrc = MSCAN_CLKSRC_XTAL; |
67 | |
68 | freq = mpc5xxx_get_bus_frequency(&ofdev->dev); |
69 | if (!freq) |
70 | return 0; |
71 | |
72 | if (*mscan_clksrc == MSCAN_CLKSRC_BUS || pvr == 0x80822011) |
73 | return freq; |
74 | |
75 | /* Determine SYS_XTAL_IN frequency from the clock domain settings */ |
76 | np_cdm = of_find_matching_node(NULL, mpc52xx_cdm_ids); |
77 | if (!np_cdm) { |
78 | dev_err(&ofdev->dev, "can't get clock node!\n" ); |
79 | return 0; |
80 | } |
81 | cdm = of_iomap(np_cdm, 0); |
82 | if (!cdm) { |
83 | of_node_put(np_cdm); |
84 | dev_err(&ofdev->dev, "can't map clock node!\n" ); |
85 | return 0; |
86 | } |
87 | |
88 | if (in_8(&cdm->ipb_clk_sel) & 0x1) |
89 | freq *= 2; |
90 | val = in_be32(&cdm->rstcfg); |
91 | |
92 | freq *= (val & (1 << 5)) ? 8 : 4; |
93 | freq /= (val & (1 << 6)) ? 12 : 16; |
94 | |
95 | of_node_put(np_cdm); |
96 | iounmap(cdm); |
97 | |
98 | return freq; |
99 | } |
100 | #else /* !CONFIG_PPC_MPC52xx */ |
101 | static u32 mpc52xx_can_get_clock(struct platform_device *ofdev, |
102 | const char *clock_name, int *mscan_clksrc) |
103 | { |
104 | return 0; |
105 | } |
106 | #endif /* CONFIG_PPC_MPC52xx */ |
107 | |
108 | #ifdef CONFIG_PPC_MPC512x |
109 | static u32 mpc512x_can_get_clock(struct platform_device *ofdev, |
110 | const char *clock_source, int *mscan_clksrc) |
111 | { |
112 | struct device_node *np; |
113 | u32 clockdiv; |
114 | enum { |
115 | CLK_FROM_AUTO, |
116 | CLK_FROM_IPS, |
117 | CLK_FROM_SYS, |
118 | CLK_FROM_REF, |
119 | } clk_from; |
120 | struct clk *clk_in, *clk_can; |
121 | unsigned long freq_calc; |
122 | struct mscan_priv *priv; |
123 | struct clk *clk_ipg; |
124 | |
125 | /* the caller passed in the clock source spec that was read from |
126 | * the device tree, get the optional clock divider as well |
127 | */ |
128 | np = ofdev->dev.of_node; |
129 | clockdiv = 1; |
130 | of_property_read_u32(np, "fsl,mscan-clock-divider" , &clockdiv); |
131 | dev_dbg(&ofdev->dev, "device tree specs: clk src[%s] div[%d]\n" , |
132 | clock_source ? clock_source : "<NULL>" , clockdiv); |
133 | |
134 | /* when clock-source is 'ip', the CANCTL1[CLKSRC] bit needs to |
135 | * get set, and the 'ips' clock is the input to the MSCAN |
136 | * component |
137 | * |
138 | * for clock-source values of 'ref' or 'sys' the CANCTL1[CLKSRC] |
139 | * bit needs to get cleared, an optional clock-divider may have |
140 | * been specified (the default value is 1), the appropriate |
141 | * MSCAN related MCLK is the input to the MSCAN component |
142 | * |
143 | * in the absence of a clock-source spec, first an optimal clock |
144 | * gets determined based on the 'sys' clock, if that fails the |
145 | * 'ref' clock is used |
146 | */ |
147 | clk_from = CLK_FROM_AUTO; |
148 | if (clock_source) { |
149 | /* interpret the device tree's spec for the clock source */ |
150 | if (!strcmp(clock_source, "ip" )) |
151 | clk_from = CLK_FROM_IPS; |
152 | else if (!strcmp(clock_source, "sys" )) |
153 | clk_from = CLK_FROM_SYS; |
154 | else if (!strcmp(clock_source, "ref" )) |
155 | clk_from = CLK_FROM_REF; |
156 | else |
157 | goto err_invalid; |
158 | dev_dbg(&ofdev->dev, "got a clk source spec[%d]\n" , clk_from); |
159 | } |
160 | if (clk_from == CLK_FROM_AUTO) { |
161 | /* no spec so far, try the 'sys' clock; round to the |
162 | * next MHz and see if we can get a multiple of 16MHz |
163 | */ |
164 | dev_dbg(&ofdev->dev, "no clk source spec, trying SYS\n" ); |
165 | clk_in = devm_clk_get(&ofdev->dev, "sys" ); |
166 | if (IS_ERR(clk_in)) |
167 | goto err_notavail; |
168 | freq_calc = clk_get_rate(clk_in); |
169 | freq_calc += 499999; |
170 | freq_calc /= 1000000; |
171 | freq_calc *= 1000000; |
172 | if ((freq_calc % 16000000) == 0) { |
173 | clk_from = CLK_FROM_SYS; |
174 | clockdiv = freq_calc / 16000000; |
175 | dev_dbg(&ofdev->dev, |
176 | "clk fit, sys[%lu] div[%d] freq[%lu]\n" , |
177 | freq_calc, clockdiv, freq_calc / clockdiv); |
178 | } |
179 | } |
180 | if (clk_from == CLK_FROM_AUTO) { |
181 | /* no spec so far, use the 'ref' clock */ |
182 | dev_dbg(&ofdev->dev, "no clk source spec, trying REF\n" ); |
183 | clk_in = devm_clk_get(&ofdev->dev, "ref" ); |
184 | if (IS_ERR(clk_in)) |
185 | goto err_notavail; |
186 | clk_from = CLK_FROM_REF; |
187 | freq_calc = clk_get_rate(clk_in); |
188 | dev_dbg(&ofdev->dev, |
189 | "clk fit, ref[%lu] (no div) freq[%lu]\n" , |
190 | freq_calc, freq_calc); |
191 | } |
192 | |
193 | /* select IPS or MCLK as the MSCAN input (returned to the caller), |
194 | * setup the MCLK mux source and rate if applicable, apply the |
195 | * optionally specified or derived above divider, and determine |
196 | * the actual resulting clock rate to return to the caller |
197 | */ |
198 | switch (clk_from) { |
199 | case CLK_FROM_IPS: |
200 | clk_can = devm_clk_get(&ofdev->dev, "ips" ); |
201 | if (IS_ERR(clk_can)) |
202 | goto err_notavail; |
203 | priv = netdev_priv(dev_get_drvdata(&ofdev->dev)); |
204 | priv->clk_can = clk_can; |
205 | freq_calc = clk_get_rate(clk_can); |
206 | *mscan_clksrc = MSCAN_CLKSRC_IPS; |
207 | dev_dbg(&ofdev->dev, "clk from IPS, clksrc[%d] freq[%lu]\n" , |
208 | *mscan_clksrc, freq_calc); |
209 | break; |
210 | case CLK_FROM_SYS: |
211 | case CLK_FROM_REF: |
212 | clk_can = devm_clk_get(&ofdev->dev, "mclk" ); |
213 | if (IS_ERR(clk_can)) |
214 | goto err_notavail; |
215 | priv = netdev_priv(dev_get_drvdata(&ofdev->dev)); |
216 | priv->clk_can = clk_can; |
217 | if (clk_from == CLK_FROM_SYS) |
218 | clk_in = devm_clk_get(&ofdev->dev, "sys" ); |
219 | if (clk_from == CLK_FROM_REF) |
220 | clk_in = devm_clk_get(&ofdev->dev, "ref" ); |
221 | if (IS_ERR(clk_in)) |
222 | goto err_notavail; |
223 | clk_set_parent(clk_can, clk_in); |
224 | freq_calc = clk_get_rate(clk_in); |
225 | freq_calc /= clockdiv; |
226 | clk_set_rate(clk_can, freq_calc); |
227 | freq_calc = clk_get_rate(clk_can); |
228 | *mscan_clksrc = MSCAN_CLKSRC_BUS; |
229 | dev_dbg(&ofdev->dev, "clk from MCLK, clksrc[%d] freq[%lu]\n" , |
230 | *mscan_clksrc, freq_calc); |
231 | break; |
232 | default: |
233 | goto err_invalid; |
234 | } |
235 | |
236 | /* the above clk_can item is used for the bitrate, access to |
237 | * the peripheral's register set needs the clk_ipg item |
238 | */ |
239 | clk_ipg = devm_clk_get(&ofdev->dev, "ipg" ); |
240 | if (IS_ERR(clk_ipg)) |
241 | goto err_notavail_ipg; |
242 | if (clk_prepare_enable(clk_ipg)) |
243 | goto err_notavail_ipg; |
244 | priv = netdev_priv(dev_get_drvdata(&ofdev->dev)); |
245 | priv->clk_ipg = clk_ipg; |
246 | |
247 | /* return the determined clock source rate */ |
248 | return freq_calc; |
249 | |
250 | err_invalid: |
251 | dev_err(&ofdev->dev, "invalid clock source specification\n" ); |
252 | /* clock source rate could not get determined */ |
253 | return 0; |
254 | |
255 | err_notavail: |
256 | dev_err(&ofdev->dev, "cannot acquire or setup bitrate clock source\n" ); |
257 | /* clock source rate could not get determined */ |
258 | return 0; |
259 | |
260 | err_notavail_ipg: |
261 | dev_err(&ofdev->dev, "cannot acquire or setup register clock\n" ); |
262 | /* clock source rate could not get determined */ |
263 | return 0; |
264 | } |
265 | |
266 | static void mpc512x_can_put_clock(struct platform_device *ofdev) |
267 | { |
268 | struct mscan_priv *priv; |
269 | |
270 | priv = netdev_priv(dev_get_drvdata(&ofdev->dev)); |
271 | if (priv->clk_ipg) |
272 | clk_disable_unprepare(priv->clk_ipg); |
273 | } |
274 | #else /* !CONFIG_PPC_MPC512x */ |
275 | static u32 mpc512x_can_get_clock(struct platform_device *ofdev, |
276 | const char *clock_name, int *mscan_clksrc) |
277 | { |
278 | return 0; |
279 | } |
280 | #define mpc512x_can_put_clock NULL |
281 | #endif /* CONFIG_PPC_MPC512x */ |
282 | |
283 | static const struct of_device_id mpc5xxx_can_table[]; |
284 | static int mpc5xxx_can_probe(struct platform_device *ofdev) |
285 | { |
286 | const struct mpc5xxx_can_data *data; |
287 | struct device_node *np = ofdev->dev.of_node; |
288 | struct net_device *dev; |
289 | struct mscan_priv *priv; |
290 | void __iomem *base; |
291 | const char *clock_name = NULL; |
292 | int irq, mscan_clksrc = 0; |
293 | int err = -ENOMEM; |
294 | |
295 | data = device_get_match_data(dev: &ofdev->dev); |
296 | if (!data) |
297 | return -EINVAL; |
298 | |
299 | base = of_iomap(node: np, index: 0); |
300 | if (!base) |
301 | return dev_err_probe(dev: &ofdev->dev, err, fmt: "couldn't ioremap\n" ); |
302 | |
303 | irq = irq_of_parse_and_map(node: np, index: 0); |
304 | if (!irq) { |
305 | dev_err(&ofdev->dev, "no irq found\n" ); |
306 | err = -ENODEV; |
307 | goto exit_unmap_mem; |
308 | } |
309 | |
310 | dev = alloc_mscandev(); |
311 | if (!dev) |
312 | goto exit_dispose_irq; |
313 | platform_set_drvdata(pdev: ofdev, data: dev); |
314 | SET_NETDEV_DEV(dev, &ofdev->dev); |
315 | |
316 | priv = netdev_priv(dev); |
317 | priv->reg_base = base; |
318 | dev->irq = irq; |
319 | |
320 | clock_name = of_get_property(node: np, name: "fsl,mscan-clock-source" , NULL); |
321 | |
322 | priv->type = data->type; |
323 | priv->can.clock.freq = data->get_clock(ofdev, clock_name, |
324 | &mscan_clksrc); |
325 | if (!priv->can.clock.freq) { |
326 | dev_err(&ofdev->dev, "couldn't get MSCAN clock properties\n" ); |
327 | goto exit_put_clock; |
328 | } |
329 | |
330 | err = register_mscandev(dev, mscan_clksrc); |
331 | if (err) { |
332 | dev_err(&ofdev->dev, "registering %s failed (err=%d)\n" , |
333 | DRV_NAME, err); |
334 | goto exit_put_clock; |
335 | } |
336 | |
337 | dev_info(&ofdev->dev, "MSCAN at 0x%p, irq %d, clock %d Hz\n" , |
338 | priv->reg_base, dev->irq, priv->can.clock.freq); |
339 | |
340 | return 0; |
341 | |
342 | exit_put_clock: |
343 | if (data->put_clock) |
344 | data->put_clock(ofdev); |
345 | free_candev(dev); |
346 | exit_dispose_irq: |
347 | irq_dispose_mapping(virq: irq); |
348 | exit_unmap_mem: |
349 | iounmap(addr: base); |
350 | |
351 | return err; |
352 | } |
353 | |
354 | static void mpc5xxx_can_remove(struct platform_device *ofdev) |
355 | { |
356 | const struct mpc5xxx_can_data *data; |
357 | struct net_device *dev = platform_get_drvdata(pdev: ofdev); |
358 | struct mscan_priv *priv = netdev_priv(dev); |
359 | |
360 | data = device_get_match_data(dev: &ofdev->dev); |
361 | |
362 | unregister_mscandev(dev); |
363 | if (data && data->put_clock) |
364 | data->put_clock(ofdev); |
365 | iounmap(addr: priv->reg_base); |
366 | irq_dispose_mapping(virq: dev->irq); |
367 | free_candev(dev); |
368 | } |
369 | |
370 | #ifdef CONFIG_PM |
371 | static struct mscan_regs saved_regs; |
372 | static int mpc5xxx_can_suspend(struct platform_device *ofdev, pm_message_t state) |
373 | { |
374 | struct net_device *dev = platform_get_drvdata(pdev: ofdev); |
375 | struct mscan_priv *priv = netdev_priv(dev); |
376 | struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base; |
377 | |
378 | _memcpy_fromio(&saved_regs, regs, sizeof(*regs)); |
379 | |
380 | return 0; |
381 | } |
382 | |
383 | static int mpc5xxx_can_resume(struct platform_device *ofdev) |
384 | { |
385 | struct net_device *dev = platform_get_drvdata(pdev: ofdev); |
386 | struct mscan_priv *priv = netdev_priv(dev); |
387 | struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base; |
388 | |
389 | regs->canctl0 |= MSCAN_INITRQ; |
390 | while (!(regs->canctl1 & MSCAN_INITAK)) |
391 | udelay(10); |
392 | |
393 | regs->canctl1 = saved_regs.canctl1; |
394 | regs->canbtr0 = saved_regs.canbtr0; |
395 | regs->canbtr1 = saved_regs.canbtr1; |
396 | regs->canidac = saved_regs.canidac; |
397 | |
398 | /* restore masks, buffers etc. */ |
399 | _memcpy_toio(®s->canidar1_0, (void *)&saved_regs.canidar1_0, |
400 | sizeof(*regs) - offsetof(struct mscan_regs, canidar1_0)); |
401 | |
402 | regs->canctl0 &= ~MSCAN_INITRQ; |
403 | regs->cantbsel = saved_regs.cantbsel; |
404 | regs->canrier = saved_regs.canrier; |
405 | regs->cantier = saved_regs.cantier; |
406 | regs->canctl0 = saved_regs.canctl0; |
407 | |
408 | return 0; |
409 | } |
410 | #endif |
411 | |
412 | static const struct mpc5xxx_can_data mpc5200_can_data = { |
413 | .type = MSCAN_TYPE_MPC5200, |
414 | .get_clock = mpc52xx_can_get_clock, |
415 | /* .put_clock not applicable */ |
416 | }; |
417 | |
418 | static const struct mpc5xxx_can_data mpc5121_can_data = { |
419 | .type = MSCAN_TYPE_MPC5121, |
420 | .get_clock = mpc512x_can_get_clock, |
421 | .put_clock = mpc512x_can_put_clock, |
422 | }; |
423 | |
424 | static const struct of_device_id mpc5xxx_can_table[] = { |
425 | { .compatible = "fsl,mpc5200-mscan" , .data = &mpc5200_can_data, }, |
426 | /* Note that only MPC5121 Rev. 2 (and later) is supported */ |
427 | { .compatible = "fsl,mpc5121-mscan" , .data = &mpc5121_can_data, }, |
428 | {}, |
429 | }; |
430 | MODULE_DEVICE_TABLE(of, mpc5xxx_can_table); |
431 | |
432 | static struct platform_driver mpc5xxx_can_driver = { |
433 | .driver = { |
434 | .name = "mpc5xxx_can" , |
435 | .of_match_table = mpc5xxx_can_table, |
436 | }, |
437 | .probe = mpc5xxx_can_probe, |
438 | .remove_new = mpc5xxx_can_remove, |
439 | #ifdef CONFIG_PM |
440 | .suspend = mpc5xxx_can_suspend, |
441 | .resume = mpc5xxx_can_resume, |
442 | #endif |
443 | }; |
444 | |
445 | module_platform_driver(mpc5xxx_can_driver); |
446 | |
447 | MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>" ); |
448 | MODULE_DESCRIPTION("Freescale MPC5xxx CAN driver" ); |
449 | MODULE_LICENSE("GPL v2" ); |
450 | |