2 * CAN bus driver for the Freescale MPC5xxx embedded CPU.
4 * Copyright (C) 2004-2005 Andrey Volkov <avolkov@varma-el.com>,
6 * Copyright (C) 2008-2009 Wolfgang Grandegger <wg@grandegger.com>
7 * Copyright (C) 2009 Wolfram Sang, Pengutronix <w.sang@pengutronix.de>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the version 2 of the GNU General Public License
11 * as published by the Free Software Foundation
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include <linux/kernel.h>
24 #include <linux/module.h>
25 #include <linux/interrupt.h>
26 #include <linux/platform_device.h>
27 #include <linux/netdevice.h>
28 #include <linux/can/dev.h>
29 #include <linux/of_platform.h>
30 #include <sysdev/fsl_soc.h>
31 #include <linux/clk.h>
33 #include <asm/mpc52xx.h>
37 #define DRV_NAME "mpc5xxx_can"
39 struct mpc5xxx_can_data
{
41 u32 (*get_clock
)(struct platform_device
*ofdev
, const char *clock_name
,
45 #ifdef CONFIG_PPC_MPC52xx
46 static struct of_device_id __devinitdata mpc52xx_cdm_ids
[] = {
47 { .compatible
= "fsl,mpc5200-cdm", },
51 static u32 __devinit
mpc52xx_can_get_clock(struct platform_device
*ofdev
,
52 const char *clock_name
,
56 struct mpc52xx_cdm __iomem
*cdm
;
57 struct device_node
*np_cdm
;
61 pvr
= mfspr(SPRN_PVR
);
64 * Either the oscillator clock (SYS_XTAL_IN) or the IP bus clock
65 * (IP_CLK) can be selected as MSCAN clock source. According to
66 * the MPC5200 user's manual, the oscillator clock is the better
67 * choice as it has less jitter. For this reason, it is selected
68 * by default. Unfortunately, it can not be selected for the old
69 * MPC5200 Rev. A chips due to a hardware bug (check errata).
71 if (clock_name
&& strcmp(clock_name
, "ip") == 0)
72 *mscan_clksrc
= MSCAN_CLKSRC_BUS
;
74 *mscan_clksrc
= MSCAN_CLKSRC_XTAL
;
76 freq
= mpc5xxx_get_bus_frequency(ofdev
->dev
.of_node
);
80 if (*mscan_clksrc
== MSCAN_CLKSRC_BUS
|| pvr
== 0x80822011)
83 /* Determine SYS_XTAL_IN frequency from the clock domain settings */
84 np_cdm
= of_find_matching_node(NULL
, mpc52xx_cdm_ids
);
86 dev_err(&ofdev
->dev
, "can't get clock node!\n");
89 cdm
= of_iomap(np_cdm
, 0);
91 if (in_8(&cdm
->ipb_clk_sel
) & 0x1)
93 val
= in_be32(&cdm
->rstcfg
);
95 freq
*= (val
& (1 << 5)) ? 8 : 4;
96 freq
/= (val
& (1 << 6)) ? 12 : 16;
103 #else /* !CONFIG_PPC_MPC52xx */
104 static u32 __devinit
mpc52xx_can_get_clock(struct platform_device
*ofdev
,
105 const char *clock_name
,
110 #endif /* CONFIG_PPC_MPC52xx */
112 #ifdef CONFIG_PPC_MPC512x
113 struct mpc512x_clockctl
{
114 u32 spmr
; /* System PLL Mode Reg */
115 u32 sccr
[2]; /* System Clk Ctrl Reg 1 & 2 */
116 u32 scfr1
; /* System Clk Freq Reg 1 */
117 u32 scfr2
; /* System Clk Freq Reg 2 */
119 u32 bcr
; /* Bread Crumb Reg */
120 u32 pccr
[12]; /* PSC Clk Ctrl Reg 0-11 */
121 u32 spccr
; /* SPDIF Clk Ctrl Reg */
122 u32 cccr
; /* CFM Clk Ctrl Reg */
123 u32 dccr
; /* DIU Clk Cnfg Reg */
124 u32 mccr
[4]; /* MSCAN Clk Ctrl Reg 1-3 */
127 static struct of_device_id __devinitdata mpc512x_clock_ids
[] = {
128 { .compatible
= "fsl,mpc5121-clock", },
132 static u32 __devinit
mpc512x_can_get_clock(struct platform_device
*ofdev
,
133 const char *clock_name
,
136 struct mpc512x_clockctl __iomem
*clockctl
;
137 struct device_node
*np_clock
;
138 struct clk
*sys_clk
, *ref_clk
;
139 int plen
, clockidx
, clocksrc
= -1;
140 u32 sys_freq
, val
, clockdiv
= 1, freq
= 0;
143 np_clock
= of_find_matching_node(NULL
, mpc512x_clock_ids
);
145 dev_err(&ofdev
->dev
, "couldn't find clock node\n");
148 clockctl
= of_iomap(np_clock
, 0);
150 dev_err(&ofdev
->dev
, "couldn't map clock registers\n");
154 /* Determine the MSCAN device index from the physical address */
155 pval
= of_get_property(ofdev
->dev
.of_node
, "reg", &plen
);
156 BUG_ON(!pval
|| plen
< sizeof(*pval
));
157 clockidx
= (*pval
& 0x80) ? 1 : 0;
162 * Clock source and divider selection: 3 different clock sources
163 * can be selected: "ip", "ref" or "sys". For the latter two, a
164 * clock divider can be defined as well. If the clock source is
165 * not specified by the device tree, we first try to find an
166 * optimal CAN source clock based on the system clock. If that
167 * is not posslible, the reference clock will be used.
169 if (clock_name
&& !strcmp(clock_name
, "ip")) {
170 *mscan_clksrc
= MSCAN_CLKSRC_IPS
;
171 freq
= mpc5xxx_get_bus_frequency(ofdev
->dev
.of_node
);
173 *mscan_clksrc
= MSCAN_CLKSRC_BUS
;
175 pval
= of_get_property(ofdev
->dev
.of_node
,
176 "fsl,mscan-clock-divider", &plen
);
177 if (pval
&& plen
== sizeof(*pval
))
182 if (!clock_name
|| !strcmp(clock_name
, "sys")) {
183 sys_clk
= clk_get(&ofdev
->dev
, "sys_clk");
185 dev_err(&ofdev
->dev
, "couldn't get sys_clk\n");
188 /* Get and round up/down sys clock rate */
190 ((clk_get_rate(sys_clk
) + 499999) / 1000000);
193 /* A multiple of 16 MHz would be optimal */
194 if ((sys_freq
% 16000000) == 0) {
196 clockdiv
= sys_freq
/ 16000000;
197 freq
= sys_freq
/ clockdiv
;
201 freq
= sys_freq
/ clockdiv
;
206 ref_clk
= clk_get(&ofdev
->dev
, "ref_clk");
208 dev_err(&ofdev
->dev
, "couldn't get ref_clk\n");
212 freq
= clk_get_rate(ref_clk
) / clockdiv
;
217 out_be32(&clockctl
->mccr
[clockidx
], 0x0);
219 /* Set source and divider */
220 val
= (clocksrc
<< 14) | ((clockdiv
- 1) << 17);
221 out_be32(&clockctl
->mccr
[clockidx
], val
);
223 out_be32(&clockctl
->mccr
[clockidx
], val
| 0x10000);
226 /* Enable MSCAN clock domain */
227 val
= in_be32(&clockctl
->sccr
[1]);
228 if (!(val
& (1 << 25)))
229 out_be32(&clockctl
->sccr
[1], val
| (1 << 25));
231 dev_dbg(&ofdev
->dev
, "using '%s' with frequency divider %d\n",
232 *mscan_clksrc
== MSCAN_CLKSRC_IPS
? "ips_clk" :
233 clocksrc
== 1 ? "ref_clk" : "sys_clk", clockdiv
);
238 of_node_put(np_clock
);
241 #else /* !CONFIG_PPC_MPC512x */
242 static u32 __devinit
mpc512x_can_get_clock(struct platform_device
*ofdev
,
243 const char *clock_name
,
248 #endif /* CONFIG_PPC_MPC512x */
250 static struct of_device_id mpc5xxx_can_table
[];
251 static int __devinit
mpc5xxx_can_probe(struct platform_device
*ofdev
)
253 const struct of_device_id
*match
;
254 struct mpc5xxx_can_data
*data
;
255 struct device_node
*np
= ofdev
->dev
.of_node
;
256 struct net_device
*dev
;
257 struct mscan_priv
*priv
;
259 const char *clock_name
= NULL
;
260 int irq
, mscan_clksrc
= 0;
263 match
= of_match_device(mpc5xxx_can_table
, &ofdev
->dev
);
268 base
= of_iomap(np
, 0);
270 dev_err(&ofdev
->dev
, "couldn't ioremap\n");
274 irq
= irq_of_parse_and_map(np
, 0);
276 dev_err(&ofdev
->dev
, "no irq found\n");
281 dev
= alloc_mscandev();
283 goto exit_dispose_irq
;
285 priv
= netdev_priv(dev
);
286 priv
->reg_base
= base
;
289 clock_name
= of_get_property(np
, "fsl,mscan-clock-source", NULL
);
292 priv
->type
= data
->type
;
293 priv
->can
.clock
.freq
= data
->get_clock(ofdev
, clock_name
,
295 if (!priv
->can
.clock
.freq
) {
296 dev_err(&ofdev
->dev
, "couldn't get MSCAN clock properties\n");
297 goto exit_free_mscan
;
300 SET_NETDEV_DEV(dev
, &ofdev
->dev
);
302 err
= register_mscandev(dev
, mscan_clksrc
);
304 dev_err(&ofdev
->dev
, "registering %s failed (err=%d)\n",
306 goto exit_free_mscan
;
309 dev_set_drvdata(&ofdev
->dev
, dev
);
311 dev_info(&ofdev
->dev
, "MSCAN at 0x%p, irq %d, clock %d Hz\n",
312 priv
->reg_base
, dev
->irq
, priv
->can
.clock
.freq
);
319 irq_dispose_mapping(irq
);
326 static int __devexit
mpc5xxx_can_remove(struct platform_device
*ofdev
)
328 struct net_device
*dev
= dev_get_drvdata(&ofdev
->dev
);
329 struct mscan_priv
*priv
= netdev_priv(dev
);
331 dev_set_drvdata(&ofdev
->dev
, NULL
);
333 unregister_mscandev(dev
);
334 iounmap(priv
->reg_base
);
335 irq_dispose_mapping(dev
->irq
);
342 static struct mscan_regs saved_regs
;
343 static int mpc5xxx_can_suspend(struct platform_device
*ofdev
, pm_message_t state
)
345 struct net_device
*dev
= dev_get_drvdata(&ofdev
->dev
);
346 struct mscan_priv
*priv
= netdev_priv(dev
);
347 struct mscan_regs
*regs
= (struct mscan_regs
*)priv
->reg_base
;
349 _memcpy_fromio(&saved_regs
, regs
, sizeof(*regs
));
354 static int mpc5xxx_can_resume(struct platform_device
*ofdev
)
356 struct net_device
*dev
= dev_get_drvdata(&ofdev
->dev
);
357 struct mscan_priv
*priv
= netdev_priv(dev
);
358 struct mscan_regs
*regs
= (struct mscan_regs
*)priv
->reg_base
;
360 regs
->canctl0
|= MSCAN_INITRQ
;
361 while (!(regs
->canctl1
& MSCAN_INITAK
))
364 regs
->canctl1
= saved_regs
.canctl1
;
365 regs
->canbtr0
= saved_regs
.canbtr0
;
366 regs
->canbtr1
= saved_regs
.canbtr1
;
367 regs
->canidac
= saved_regs
.canidac
;
369 /* restore masks, buffers etc. */
370 _memcpy_toio(®s
->canidar1_0
, (void *)&saved_regs
.canidar1_0
,
371 sizeof(*regs
) - offsetof(struct mscan_regs
, canidar1_0
));
373 regs
->canctl0
&= ~MSCAN_INITRQ
;
374 regs
->cantbsel
= saved_regs
.cantbsel
;
375 regs
->canrier
= saved_regs
.canrier
;
376 regs
->cantier
= saved_regs
.cantier
;
377 regs
->canctl0
= saved_regs
.canctl0
;
383 static struct mpc5xxx_can_data __devinitdata mpc5200_can_data
= {
384 .type
= MSCAN_TYPE_MPC5200
,
385 .get_clock
= mpc52xx_can_get_clock
,
388 static struct mpc5xxx_can_data __devinitdata mpc5121_can_data
= {
389 .type
= MSCAN_TYPE_MPC5121
,
390 .get_clock
= mpc512x_can_get_clock
,
393 static struct of_device_id __devinitdata mpc5xxx_can_table
[] = {
394 { .compatible
= "fsl,mpc5200-mscan", .data
= &mpc5200_can_data
, },
395 /* Note that only MPC5121 Rev. 2 (and later) is supported */
396 { .compatible
= "fsl,mpc5121-mscan", .data
= &mpc5121_can_data
, },
400 static struct platform_driver mpc5xxx_can_driver
= {
402 .name
= "mpc5xxx_can",
403 .owner
= THIS_MODULE
,
404 .of_match_table
= mpc5xxx_can_table
,
406 .probe
= mpc5xxx_can_probe
,
407 .remove
= __devexit_p(mpc5xxx_can_remove
),
409 .suspend
= mpc5xxx_can_suspend
,
410 .resume
= mpc5xxx_can_resume
,
414 module_platform_driver(mpc5xxx_can_driver
);
416 MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
417 MODULE_DESCRIPTION("Freescale MPC5xxx CAN driver");
418 MODULE_LICENSE("GPL v2");