2 * MPC8560ADS board specific routines
4 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
6 * Copyright 2004 Freescale Semiconductor Inc.
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
14 #include <linux/stddef.h>
15 #include <linux/kernel.h>
16 #include <linux/init.h>
17 #include <linux/errno.h>
18 #include <linux/reboot.h>
19 #include <linux/pci.h>
20 #include <linux/kdev_t.h>
21 #include <linux/major.h>
22 #include <linux/console.h>
23 #include <linux/delay.h>
24 #include <linux/seq_file.h>
25 #include <linux/root_dev.h>
26 #include <linux/serial.h>
27 #include <linux/tty.h> /* for linux/serial_core.h */
28 #include <linux/serial_core.h>
29 #include <linux/initrd.h>
30 #include <linux/module.h>
31 #include <linux/fsl_devices.h>
32 #include <linux/fs_enet_pd.h>
34 #include <asm/system.h>
35 #include <asm/pgtable.h>
37 #include <asm/atomic.h>
40 #include <asm/machdep.h>
41 #include <asm/open_pic.h>
42 #include <asm/bootinfo.h>
43 #include <asm/pci-bridge.h>
44 #include <asm/mpc85xx.h>
46 #include <asm/immap_85xx.h>
48 #include <asm/ppc_sys.h>
50 #include <mm/mmu_decl.h>
52 #include <syslib/cpm2_pic.h>
53 #include <syslib/ppc85xx_common.h>
54 #include <syslib/ppc85xx_setup.h>
57 /* ************************************************************************
59 * Setup the architecture
62 static void init_fcc_ioports(void)
70 io
= &immap
->im_ioport
;
71 /* FCC2/3 are on the ports B/C. */
72 tempval
= in_be32(&io
->iop_pdirb
);
73 tempval
&= ~PB2_DIRB0
;
75 out_be32(&io
->iop_pdirb
, tempval
);
77 tempval
= in_be32(&io
->iop_psorb
);
78 tempval
&= ~PB2_PSORB0
;
79 tempval
|= PB2_PSORB1
;
80 out_be32(&io
->iop_psorb
, tempval
);
82 tempval
= in_be32(&io
->iop_pparb
);
83 tempval
|= (PB2_DIRB0
| PB2_DIRB1
);
84 out_be32(&io
->iop_pparb
, tempval
);
86 tempval
= in_be32(&io
->iop_pdirb
);
87 tempval
&= ~PB3_DIRB0
;
89 out_be32(&io
->iop_pdirb
, tempval
);
91 tempval
= in_be32(&io
->iop_psorb
);
92 tempval
&= ~PB3_PSORB0
;
93 tempval
|= PB3_PSORB1
;
94 out_be32(&io
->iop_psorb
, tempval
);
96 tempval
= in_be32(&io
->iop_pparb
);
97 tempval
|= (PB3_DIRB0
| PB3_DIRB1
);
98 out_be32(&io
->iop_pparb
, tempval
);
100 tempval
= in_be32(&io
->iop_pdirc
);
101 tempval
|= PC3_DIRC1
;
102 out_be32(&io
->iop_pdirc
, tempval
);
104 tempval
= in_be32(&io
->iop_pparc
);
105 tempval
|= PC3_DIRC1
;
106 out_be32(&io
->iop_pparc
, tempval
);
108 /* Port C has clocks...... */
109 tempval
= in_be32(&io
->iop_psorc
);
110 tempval
&= ~(CLK_TRX
);
111 out_be32(&io
->iop_psorc
, tempval
);
113 tempval
= in_be32(&io
->iop_pdirc
);
114 tempval
&= ~(CLK_TRX
);
115 out_be32(&io
->iop_pdirc
, tempval
);
116 tempval
= in_be32(&io
->iop_pparc
);
117 tempval
|= (CLK_TRX
);
118 out_be32(&io
->iop_pparc
, tempval
);
120 /* Configure Serial Interface clock routing.
121 * First, clear all FCC bits to zero,
122 * then set the ones we want.
124 immap
->im_cpmux
.cmx_fcr
&= ~(CPMUX_CLK_MASK
);
125 immap
->im_cpmux
.cmx_fcr
|= CPMUX_CLK_ROUTE
;
129 mpc8560ads_setup_arch(void)
131 bd_t
*binfo
= (bd_t
*) __res
;
133 struct gianfar_platform_data
*pdata
;
134 struct gianfar_mdio_data
*mdata
;
135 struct fs_platform_info
*fpi
;
139 /* get the core frequency */
140 freq
= binfo
->bi_intfreq
;
143 ppc_md
.progress("mpc8560ads_setup_arch()", 0);
145 /* Set loops_per_jiffy to a half-way reasonable value,
146 for use until calibrate_delay gets called. */
147 loops_per_jiffy
= freq
/ HZ
;
150 /* setup PCI host bridges */
151 mpc85xx_setup_hose();
154 /* setup the board related info for the MDIO bus */
155 mdata
= (struct gianfar_mdio_data
*) ppc_sys_get_pdata(MPC85xx_MDIO
);
157 mdata
->irq
[0] = MPC85xx_IRQ_EXT5
;
158 mdata
->irq
[1] = MPC85xx_IRQ_EXT5
;
159 mdata
->irq
[2] = PHY_POLL
;
160 mdata
->irq
[3] = MPC85xx_IRQ_EXT5
;
161 mdata
->irq
[31] = PHY_POLL
;
163 /* setup the board related information for the enet controllers */
164 pdata
= (struct gianfar_platform_data
*) ppc_sys_get_pdata(MPC85xx_TSEC1
);
166 pdata
->board_flags
= FSL_GIANFAR_BRD_HAS_PHY_INTR
;
169 memcpy(pdata
->mac_addr
, binfo
->bi_enetaddr
, 6);
172 pdata
= (struct gianfar_platform_data
*) ppc_sys_get_pdata(MPC85xx_TSEC2
);
174 pdata
->board_flags
= FSL_GIANFAR_BRD_HAS_PHY_INTR
;
177 memcpy(pdata
->mac_addr
, binfo
->bi_enet1addr
, 6);
181 ppc_sys_device_remove(MPC85xx_CPM_FCC1
);
183 fpi
= (struct fs_platform_info
*) ppc_sys_get_pdata(MPC85xx_CPM_FCC2
);
185 memcpy(fpi
->macaddr
, binfo
->bi_enet2addr
, 6);
186 fpi
->bus_id
= "0:02";
188 fpi
->dpram_offset
= (u32
)cpm2_immr
->im_dprambase
;
189 fpi
->fcc_regs_c
= (u32
)&cpm2_immr
->im_fcc_c
[1];
192 fpi
= (struct fs_platform_info
*) ppc_sys_get_pdata(MPC85xx_CPM_FCC3
);
194 memcpy(fpi
->macaddr
, binfo
->bi_enet2addr
, 6);
195 fpi
->macaddr
[5] += 1;
196 fpi
->bus_id
= "0:03";
198 fpi
->dpram_offset
= (u32
)cpm2_immr
->im_dprambase
;
199 fpi
->fcc_regs_c
= (u32
)&cpm2_immr
->im_fcc_c
[2];
202 #ifdef CONFIG_BLK_DEV_INITRD
204 ROOT_DEV
= Root_RAM0
;
207 #ifdef CONFIG_ROOT_NFS
210 ROOT_DEV
= Root_HDA1
;
214 static irqreturn_t
cpm2_cascade(int irq
, void *dev_id
)
216 while ((irq
= cpm2_get_irq()) >= 0)
221 static struct irqaction cpm2_irqaction
= {
222 .handler
= cpm2_cascade
,
223 .flags
= IRQF_DISABLED
,
224 .mask
= CPU_MASK_NONE
,
225 .name
= "cpm2_cascade",
229 mpc8560_ads_init_IRQ(void)
232 mpc85xx_ads_init_IRQ();
237 setup_irq(MPC85xx_IRQ_CPM
, &cpm2_irqaction
);
244 /* ************************************************************************ */
246 platform_init(unsigned long r3
, unsigned long r4
, unsigned long r5
,
247 unsigned long r6
, unsigned long r7
)
249 /* parse_bootinfo must always be called first */
250 parse_bootinfo(find_bootinfo());
253 * If we were passed in a board information, copy it into the
254 * residual data area.
257 memcpy((void *) __res
, (void *) (r3
+ KERNELBASE
),
261 #if defined(CONFIG_BLK_DEV_INITRD)
263 * If the init RAM disk has been configured in, and there's a valid
264 * starting address for it, set it up.
267 initrd_start
= r4
+ KERNELBASE
;
268 initrd_end
= r5
+ KERNELBASE
;
270 #endif /* CONFIG_BLK_DEV_INITRD */
272 /* Copy the kernel command line arguments to a safe place. */
275 *(char *) (r7
+ KERNELBASE
) = 0;
276 strcpy(cmd_line
, (char *) (r6
+ KERNELBASE
));
279 identify_ppc_sys_by_id(mfspr(SPRN_SVR
));
281 /* setup the PowerPC module struct */
282 ppc_md
.setup_arch
= mpc8560ads_setup_arch
;
283 ppc_md
.show_cpuinfo
= mpc85xx_ads_show_cpuinfo
;
285 ppc_md
.init_IRQ
= mpc8560_ads_init_IRQ
;
286 ppc_md
.get_irq
= openpic_get_irq
;
288 ppc_md
.restart
= mpc85xx_restart
;
289 ppc_md
.power_off
= mpc85xx_power_off
;
290 ppc_md
.halt
= mpc85xx_halt
;
292 ppc_md
.find_end_of_memory
= mpc85xx_find_end_of_memory
;
294 ppc_md
.time_init
= NULL
;
295 ppc_md
.set_rtc_time
= NULL
;
296 ppc_md
.get_rtc_time
= NULL
;
297 ppc_md
.calibrate_decr
= mpc85xx_calibrate_decr
;
300 ppc_md
.progress("mpc8560ads_init(): exit", 0);