1 /*arch/ppc/platforms/mpc866ads-setup.c
3 * Platform setup for the Freescale mpc866ads board
5 * Vitaly Bordug <vbordug@ru.mvista.com>
7 * Copyright 2005-2006 MontaVista Software Inc.
9 * This file is licensed under the terms of the GNU General Public License
10 * version 2. This program is licensed "as is" without any warranty of any
11 * kind, whether express or implied.
14 #include <linux/init.h>
15 #include <linux/module.h>
16 #include <linux/param.h>
17 #include <linux/string.h>
18 #include <linux/ioport.h>
19 #include <linux/device.h>
21 #include <linux/fs_enet_pd.h>
22 #include <linux/fs_uart_pd.h>
23 #include <linux/mii.h>
25 #include <asm/delay.h>
27 #include <asm/machdep.h>
29 #include <asm/processor.h>
30 #include <asm/system.h>
32 #include <asm/ppcboot.h>
33 #include <asm/8xx_immap.h>
34 #include <asm/commproc.h>
35 #include <asm/ppc_sys.h>
36 #include <asm/mpc8xx.h>
38 extern unsigned char __res[];
40 static void setup_fec1_ioports(void);
41 static void setup_scc1_ioports(void);
42 static void setup_smc1_ioports(void);
43 static void setup_smc2_ioports(void);
45 static struct fs_mii_fec_platform_info mpc8xx_mdio_fec_pdata;
47 static struct fs_mii_fec_platform_info mpc8xx_mdio_fec_pdata;
49 static struct fs_platform_info mpc8xx_enet_pdata[] = {
58 .init_ioports = setup_fec1_ioports,
71 .init_ioports = setup_scc1_ioports,
73 .bus_id = "fixed@100:1",
77 static struct fs_uart_platform_info mpc866_uart_pdata[] = {
80 .fs_no = fsid_smc1_uart,
81 .init_ioports = setup_smc1_ioports,
89 .fs_no = fsid_smc2_uart,
90 .init_ioports = setup_smc2_ioports,
98 void __init board_init(void)
100 volatile cpm8xx_t *cp = cpmp;
103 bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
105 if (bcsr_io == NULL) {
106 printk(KERN_CRIT "Could not remap BCSR1\n");
110 #ifdef CONFIG_SERIAL_CPM_SMC1
111 cp->cp_simode &= ~(0xe0000000 >> 17); /* brg1 */
112 clrbits32(bcsr_io,(0x80000000 >> 7));
113 cp->cp_smc[0].smc_smcm |= (SMCM_RX | SMCM_TX);
114 cp->cp_smc[0].smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
116 setbits32(bcsr_io,(0x80000000 >> 7));
118 cp->cp_pbpar &= ~(0x000000c0);
119 cp->cp_pbdir |= 0x000000c0;
120 cp->cp_smc[0].smc_smcmr = 0;
121 cp->cp_smc[0].smc_smce = 0;
124 #ifdef CONFIG_SERIAL_CPM_SMC2
125 cp->cp_simode &= ~(0xe0000000 >> 1);
126 cp->cp_simode |= (0x20000000 >> 1); /* brg2 */
127 clrbits32(bcsr_io,(0x80000000 >> 13));
128 cp->cp_smc[1].smc_smcm |= (SMCM_RX | SMCM_TX);
129 cp->cp_smc[1].smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
131 clrbits32(bcsr_io,(0x80000000 >> 13));
132 cp->cp_pbpar &= ~(0x00000c00);
133 cp->cp_pbdir |= 0x00000c00;
134 cp->cp_smc[1].smc_smcmr = 0;
135 cp->cp_smc[1].smc_smce = 0;
140 static void setup_fec1_ioports(struct fs_platform_info*)
142 immap_t *immap = (immap_t *) IMAP_ADDR;
144 setbits16(&immap->im_ioport.iop_pdpar, 0x1fff);
145 setbits16(&immap->im_ioport.iop_pddir, 0x1fff);
148 static void setup_scc1_ioports(struct fs_platform_info*)
150 immap_t *immap = (immap_t *) IMAP_ADDR;
153 bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
155 if (bcsr_io == NULL) {
156 printk(KERN_CRIT "Could not remap BCSR1\n");
162 clrbits32(bcsr_io,BCSR1_ETHEN);
164 /* Configure port A pins for Txd and Rxd.
166 /* Disable receive and transmit in case EPPC-Bug started it.
168 setbits16(&immap->im_ioport.iop_papar, PA_ENET_RXD | PA_ENET_TXD);
169 clrbits16(&immap->im_ioport.iop_padir, PA_ENET_RXD | PA_ENET_TXD);
170 clrbits16(&immap->im_ioport.iop_paodr, PA_ENET_TXD);
172 /* Configure port C pins to enable CLSN and RENA.
174 clrbits16(&immap->im_ioport.iop_pcpar, PC_ENET_CLSN | PC_ENET_RENA);
175 clrbits16(&immap->im_ioport.iop_pcdir, PC_ENET_CLSN | PC_ENET_RENA);
176 setbits16(&immap->im_ioport.iop_pcso, PC_ENET_CLSN | PC_ENET_RENA);
177 /* Configure port A for TCLK and RCLK.
179 setbits16(&immap->im_ioport.iop_papar, PA_ENET_TCLK | PA_ENET_RCLK);
180 clrbits16(&immap->im_ioport.iop_padir, PA_ENET_TCLK | PA_ENET_RCLK);
181 clrbits32(&immap->im_cpm.cp_pbpar, PB_ENET_TENA);
182 clrbits32(&immap->im_cpm.cp_pbdir, PB_ENET_TENA);
184 /* Configure Serial Interface clock routing.
185 * First, clear all SCC bits to zero, then set the ones we want.
187 clrbits32(&immap->im_cpm.cp_sicr, SICR_ENET_MASK);
188 setbits32(&immap->im_cpm.cp_sicr, SICR_ENET_CLKRT);
190 /* In the original SCC enet driver the following code is placed at
191 the end of the initialization */
192 setbits32(&immap->im_cpm.cp_pbpar, PB_ENET_TENA);
193 setbits32(&immap->im_cpm.cp_pbdir, PB_ENET_TENA);
197 static void setup_smc1_ioports(struct fs_uart_platform_info*)
199 immap_t *immap = (immap_t *) IMAP_ADDR;
201 unsigned int iobits = 0x000000c0;
203 bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
205 if (bcsr_io == NULL) {
206 printk(KERN_CRIT "Could not remap BCSR1\n");
210 clrbits32(bcsr_io,BCSR1_RS232EN_1);
213 setbits32(&immap->im_cpm.cp_pbpar, iobits);
214 clrbits32(&immap->im_cpm.cp_pbdir, iobits);
215 clrbits16(&immap->im_cpm.cp_pbodr, iobits);
219 static void setup_smc2_ioports(struct fs_uart_platform_info*)
221 immap_t *immap = (immap_t *) IMAP_ADDR;
223 unsigned int iobits = 0x00000c00;
225 bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
227 if (bcsr_io == NULL) {
228 printk(KERN_CRIT "Could not remap BCSR1\n");
232 clrbits32(bcsr_io,BCSR1_RS232EN_2);
236 #ifndef CONFIG_SERIAL_CPM_ALT_SMC2
237 setbits32(&immap->im_cpm.cp_pbpar, iobits);
238 clrbits32(&immap->im_cpm.cp_pbdir, iobits);
239 clrbits16(&immap->im_cpm.cp_pbodr, iobits);
241 setbits16(&immap->im_ioport.iop_papar, iobits);
242 clrbits16(&immap->im_ioport.iop_padir, iobits);
243 clrbits16(&immap->im_ioport.iop_paodr, iobits);
248 static int ma_count = 0;
250 static void mpc866ads_fixup_enet_pdata(struct platform_device *pdev, int fs_no)
252 struct fs_platform_info *fpi;
254 volatile cpm8xx_t *cp;
255 bd_t *bd = (bd_t *) __res;
259 /* Get pointer to Communication Processor */
262 if(fs_no >= ARRAY_SIZE(mpc8xx_enet_pdata)) {
263 printk(KERN_ERR"No network-suitable #%d device on bus", fs_no);
268 fpi = &mpc8xx_enet_pdata[fs_no];
270 pdev->dev.platform_data = fpi;
272 e = (unsigned char *)&bd->bi_enetaddr;
273 for (i = 0; i < 6; i++)
274 fpi->macaddr[i] = *e++;
276 fpi->macaddr[5] += ma_count++;
279 static void mpc866ads_fixup_fec_enet_pdata(struct platform_device *pdev,
282 /* This is for FEC devices only */
283 if (!pdev || !pdev->name || (!strstr(pdev->name, "fsl-cpm-fec")))
285 mpc866ads_fixup_enet_pdata(pdev, fsid_fec1 + pdev->id - 1);
288 static void mpc866ads_fixup_scc_enet_pdata(struct platform_device *pdev,
291 /* This is for SCC devices only */
292 if (!pdev || !pdev->name || (!strstr(pdev->name, "fsl-cpm-scc")))
295 mpc866ads_fixup_enet_pdata(pdev, fsid_scc1 + pdev->id - 1);
298 static void __init mpc866ads_fixup_uart_pdata(struct platform_device *pdev,
301 bd_t *bd = (bd_t *) __res;
302 struct fs_uart_platform_info *pinfo;
303 int num = ARRAY_SIZE(mpc866_uart_pdata);
305 int id = fs_uart_id_smc2fsid(idx);
307 /* no need to alter anything if console */
308 if ((id < num) && (!pdev->dev.platform_data)) {
309 pinfo = &mpc866_uart_pdata[id];
310 pinfo->uart_clk = bd->bi_intfreq;
311 pdev->dev.platform_data = pinfo;
315 static int mpc866ads_platform_notify(struct device *dev)
317 static const struct platform_notify_dev_map dev_map[] = {
319 .bus_id = "fsl-cpm-fec",
320 .rtn = mpc866ads_fixup_fec_enet_pdata,
323 .bus_id = "fsl-cpm-scc",
324 .rtn = mpc866ads_fixup_scc_enet_pdata,
327 .bus_id = "fsl-cpm-smc:uart",
328 .rtn = mpc866ads_fixup_uart_pdata
335 platform_notify_map(dev_map,dev);
340 int __init mpc866ads_init(void)
342 bd_t *bd = (bd_t *) __res;
343 struct fs_mii_fec_platform_info* fmpi;
345 printk(KERN_NOTICE "mpc866ads: Init\n");
347 platform_notify = mpc866ads_platform_notify;
349 ppc_sys_device_initfunc();
350 ppc_sys_device_disable_all();
352 #ifdef CONFIG_MPC8xx_SECOND_ETH_SCC1
353 ppc_sys_device_enable(MPC8xx_CPM_SCC1);
355 ppc_sys_device_enable(MPC8xx_CPM_FEC1);
357 ppc_sys_device_enable(MPC8xx_MDIO_FEC);
359 fmpi = ppc_sys_platform_devices[MPC8xx_MDIO_FEC].dev.platform_data =
360 &mpc8xx_mdio_fec_pdata;
362 fmpi->mii_speed = ((((bd->bi_intfreq + 4999999) / 2500000) / 2) & 0x3F) << 1;
363 /* No PHY interrupt line here */
366 /* Since either of the uarts could be used as console, they need to ready */
367 #ifdef CONFIG_SERIAL_CPM_SMC1
368 ppc_sys_device_enable(MPC8xx_CPM_SMC1);
369 ppc_sys_device_setfunc(MPC8xx_CPM_SMC1, PPC_SYS_FUNC_UART);
372 #ifdef CONFIG_SERIAL_CPM_SMC
373 ppc_sys_device_enable(MPC8xx_CPM_SMC2);
374 ppc_sys_device_setfunc(MPC8xx_CPM_SMC2, PPC_SYS_FUNC_UART);
376 ppc_sys_device_enable(MPC8xx_MDIO_FEC);
378 fmpi = ppc_sys_platform_devices[MPC8xx_MDIO_FEC].dev.platform_data =
379 &mpc8xx_mdio_fec_pdata;
381 fmpi->mii_speed = ((((bd->bi_intfreq + 4999999) / 2500000) / 2) & 0x3F) << 1;
382 /* No PHY interrupt line here */
389 To prevent confusion, console selection is gross:
390 by 0 assumed SMC1 and by 1 assumed SMC2
392 struct platform_device* early_uart_get_pdev(int index)
394 bd_t *bd = (bd_t *) __res;
395 struct fs_uart_platform_info *pinfo;
397 struct platform_device* pdev = NULL;
398 if(index) { /*assume SMC2 here*/
399 pdev = &ppc_sys_platform_devices[MPC8xx_CPM_SMC2];
400 pinfo = &mpc866_uart_pdata[1];
401 } else { /*over SMC1*/
402 pdev = &ppc_sys_platform_devices[MPC8xx_CPM_SMC1];
403 pinfo = &mpc866_uart_pdata[0];
406 pinfo->uart_clk = bd->bi_intfreq;
407 pdev->dev.platform_data = pinfo;
408 ppc_sys_fixup_mem_resource(pdev, IMAP_ADDR);
412 arch_initcall(mpc866ads_init);