1/*arch/ppc/platforms/mpc885ads_setup.c 2 * 3 * Platform setup for the Freescale mpc885ads board 4 * 5 * Vitaly Bordug <vbordug@ru.mvista.com> 6 * 7 * Copyright 2005 MontaVista Software Inc. 8 * 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. 12 */ 13 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> 20 21#include <linux/fs_enet_pd.h> 22#include <linux/fs_uart_pd.h> 23#include <linux/mii.h> 24 25#include <asm/delay.h> 26#include <asm/io.h> 27#include <asm/machdep.h> 28#include <asm/page.h> 29#include <asm/processor.h> 30#include <asm/system.h> 31#include <asm/time.h> 32#include <asm/ppcboot.h> 33#include <asm/8xx_immap.h> 34#include <asm/commproc.h> 35#include <asm/ppc_sys.h> 36 37extern unsigned char __res[]; 38static void setup_smc1_ioports(struct fs_uart_platform_info*); 39static void setup_smc2_ioports(struct fs_uart_platform_info*); 40 41static struct fs_mii_fec_platform_info mpc8xx_mdio_fec_pdata; 42static void setup_fec1_ioports(struct fs_platform_info*); 43static void setup_fec2_ioports(struct fs_platform_info*); 44static void setup_scc3_ioports(struct fs_platform_info*); 45 46static struct fs_uart_platform_info mpc885_uart_pdata[] = { 47 [fsid_smc1_uart] = { 48 .brg = 1, 49 .fs_no = fsid_smc1_uart, 50 .init_ioports = setup_smc1_ioports, 51 .tx_num_fifo = 4, 52 .tx_buf_size = 32, 53 .rx_num_fifo = 4, 54 .rx_buf_size = 32, 55 }, 56 [fsid_smc2_uart] = { 57 .brg = 2, 58 .fs_no = fsid_smc2_uart, 59 .init_ioports = setup_smc2_ioports, 60 .tx_num_fifo = 4, 61 .tx_buf_size = 32, 62 .rx_num_fifo = 4, 63 .rx_buf_size = 32, 64 }, 65}; 66 67static struct fs_platform_info mpc8xx_enet_pdata[] = { 68 [fsid_fec1] = { 69 .rx_ring = 128, 70 .tx_ring = 16, 71 .rx_copybreak = 240, 72 73 .use_napi = 1, 74 .napi_weight = 17, 75 76 .init_ioports = setup_fec1_ioports, 77 78 .bus_id = "0:00", 79 .has_phy = 1, 80 }, 81 [fsid_fec2] = { 82 .rx_ring = 128, 83 .tx_ring = 16, 84 .rx_copybreak = 240, 85 86 .use_napi = 1, 87 .napi_weight = 17, 88 89 .init_ioports = setup_fec2_ioports, 90 91 .bus_id = "0:01", 92 .has_phy = 1, 93 }, 94 [fsid_scc3] = { 95 .rx_ring = 64, 96 .tx_ring = 8, 97 .rx_copybreak = 240, 98 99 .use_napi = 1, 100 .napi_weight = 17, 101 102 .init_ioports = setup_scc3_ioports, 103#ifdef CONFIG_FIXED_MII_10_FDX 104 .bus_id = "fixed@100:1", 105#else 106 .bus_id = "0:02", 107 #endif 108 }, 109}; 110 111void __init board_init(void) 112{ 113 cpm8xx_t *cp = cpmp; 114 unsigned int *bcsr_io; 115 116#ifdef CONFIG_FS_ENET 117 immap_t *immap = (immap_t *) IMAP_ADDR; 118#endif 119 bcsr_io = ioremap(BCSR1, sizeof(unsigned long)); 120 121 if (bcsr_io == NULL) { 122 printk(KERN_CRIT "Could not remap BCSR\n"); 123 return; 124 } 125#ifdef CONFIG_SERIAL_CPM_SMC1 126 cp->cp_simode &= ~(0xe0000000 >> 17); /* brg1 */ 127 clrbits32(bcsr_io, BCSR1_RS232EN_1); 128 cp->cp_smc[0].smc_smcm |= (SMCM_RX | SMCM_TX); 129 cp->cp_smc[0].smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); 130#else 131 setbits32(bcsr_io,BCSR1_RS232EN_1); 132 cp->cp_smc[0].smc_smcmr = 0; 133 cp->cp_smc[0].smc_smce = 0; 134#endif 135 136#ifdef CONFIG_SERIAL_CPM_SMC2 137 cp->cp_simode &= ~(0xe0000000 >> 1); 138 cp->cp_simode |= (0x20000000 >> 1); /* brg2 */ 139 clrbits32(bcsr_io,BCSR1_RS232EN_2); 140 cp->cp_smc[1].smc_smcm |= (SMCM_RX | SMCM_TX); 141 cp->cp_smc[1].smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); 142#else 143 setbits32(bcsr_io,BCSR1_RS232EN_2); 144 cp->cp_smc[1].smc_smcmr = 0; 145 cp->cp_smc[1].smc_smce = 0; 146#endif 147 iounmap(bcsr_io); 148 149#ifdef CONFIG_FS_ENET 150 /* use MDC for MII (common) */ 151 setbits16(&immap->im_ioport.iop_pdpar, 0x0080); 152 clrbits16(&immap->im_ioport.iop_pddir, 0x0080); 153 bcsr_io = ioremap(BCSR5, sizeof(unsigned long)); 154 clrbits32(bcsr_io,BCSR5_MII1_EN); 155 clrbits32(bcsr_io,BCSR5_MII1_RST); 156#ifdef CONFIG_MPC8xx_SECOND_ETH_FEC2 157 clrbits32(bcsr_io,BCSR5_MII2_EN); 158 clrbits32(bcsr_io,BCSR5_MII2_RST); 159#endif 160 iounmap(bcsr_io); 161#endif 162} 163 164static void setup_fec1_ioports(struct fs_platform_info* pdata) 165{ 166 immap_t *immap = (immap_t *) IMAP_ADDR; 167 168 /* configure FEC1 pins */ 169 setbits16(&immap->im_ioport.iop_papar, 0xf830); 170 setbits16(&immap->im_ioport.iop_padir, 0x0830); 171 clrbits16(&immap->im_ioport.iop_padir, 0xf000); 172 setbits32(&immap->im_cpm.cp_pbpar, 0x00001001); 173 174 clrbits32(&immap->im_cpm.cp_pbdir, 0x00001001); 175 setbits16(&immap->im_ioport.iop_pcpar, 0x000c); 176 clrbits16(&immap->im_ioport.iop_pcdir, 0x000c); 177 setbits32(&immap->im_cpm.cp_pepar, 0x00000003); 178 179 setbits32(&immap->im_cpm.cp_pedir, 0x00000003); 180 clrbits32(&immap->im_cpm.cp_peso, 0x00000003); 181 clrbits32(&immap->im_cpm.cp_cptr, 0x00000100); 182} 183 184static void setup_fec2_ioports(struct fs_platform_info* pdata) 185{ 186 immap_t *immap = (immap_t *) IMAP_ADDR; 187 188 /* configure FEC2 pins */ 189 setbits32(&immap->im_cpm.cp_pepar, 0x0003fffc); 190 setbits32(&immap->im_cpm.cp_pedir, 0x0003fffc); 191 clrbits32(&immap->im_cpm.cp_peso, 0x000087fc); 192 setbits32(&immap->im_cpm.cp_peso, 0x00037800); 193 clrbits32(&immap->im_cpm.cp_cptr, 0x00000080); 194} 195 196static void setup_scc3_ioports(struct fs_platform_info* pdata) 197{ 198 immap_t *immap = (immap_t *) IMAP_ADDR; 199 unsigned *bcsr_io; 200 201 bcsr_io = ioremap(BCSR_ADDR, BCSR_SIZE); 202 203 if (bcsr_io == NULL) { 204 printk(KERN_CRIT "Could not remap BCSR\n"); 205 return; 206 } 207 208 /* Enable the PHY. 209 */ 210 clrbits32(bcsr_io+4, BCSR4_ETH10_RST); 211 udelay(1000); 212 setbits32(bcsr_io+4, BCSR4_ETH10_RST); 213 /* Configure port A pins for Txd and Rxd. 214 */ 215 setbits16(&immap->im_ioport.iop_papar, PA_ENET_RXD | PA_ENET_TXD); 216 clrbits16(&immap->im_ioport.iop_padir, PA_ENET_RXD | PA_ENET_TXD); 217 218 /* Configure port C pins to enable CLSN and RENA. 219 */ 220 clrbits16(&immap->im_ioport.iop_pcpar, PC_ENET_CLSN | PC_ENET_RENA); 221 clrbits16(&immap->im_ioport.iop_pcdir, PC_ENET_CLSN | PC_ENET_RENA); 222 setbits16(&immap->im_ioport.iop_pcso, PC_ENET_CLSN | PC_ENET_RENA); 223 224 /* Configure port E for TCLK and RCLK. 225 */ 226 setbits32(&immap->im_cpm.cp_pepar, PE_ENET_TCLK | PE_ENET_RCLK); 227 clrbits32(&immap->im_cpm.cp_pepar, PE_ENET_TENA); 228 clrbits32(&immap->im_cpm.cp_pedir, 229 PE_ENET_TCLK | PE_ENET_RCLK | PE_ENET_TENA); 230 clrbits32(&immap->im_cpm.cp_peso, PE_ENET_TCLK | PE_ENET_RCLK); 231 setbits32(&immap->im_cpm.cp_peso, PE_ENET_TENA); 232 233 /* Configure Serial Interface clock routing. 234 * First, clear all SCC bits to zero, then set the ones we want. 235 */ 236 clrbits32(&immap->im_cpm.cp_sicr, SICR_ENET_MASK); 237 setbits32(&immap->im_cpm.cp_sicr, SICR_ENET_CLKRT); 238 239 /* Disable Rx and Tx. SMC1 sshould be stopped if SCC3 eternet are used. 240 */ 241 immap->im_cpm.cp_smc[0].smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); 242 /* On the MPC885ADS SCC ethernet PHY is initialized in the full duplex mode 243 * by H/W setting after reset. SCC ethernet controller support only half duplex. 244 * This discrepancy of modes causes a lot of carrier lost errors. 245 */ 246 247 /* In the original SCC enet driver the following code is placed at 248 the end of the initialization */ 249 setbits32(&immap->im_cpm.cp_pepar, PE_ENET_TENA); 250 clrbits32(&immap->im_cpm.cp_pedir, PE_ENET_TENA); 251 setbits32(&immap->im_cpm.cp_peso, PE_ENET_TENA); 252 253 setbits32(bcsr_io+4, BCSR1_ETHEN); 254 iounmap(bcsr_io); 255} 256 257static int mac_count = 0; 258 259static void mpc885ads_fixup_enet_pdata(struct platform_device *pdev, int fs_no) 260{ 261 struct fs_platform_info *fpi; 262 bd_t *bd = (bd_t *) __res; 263 char *e; 264 int i; 265 266 if(fs_no >= ARRAY_SIZE(mpc8xx_enet_pdata)) { 267 printk(KERN_ERR"No network-suitable #%d device on bus", fs_no); 268 return; 269 } 270 271 fpi = &mpc8xx_enet_pdata[fs_no]; 272 273 switch (fs_no) { 274 case fsid_fec1: 275 fpi->init_ioports = &setup_fec1_ioports; 276 break; 277 case fsid_fec2: 278 fpi->init_ioports = &setup_fec2_ioports; 279 break; 280 case fsid_scc3: 281 fpi->init_ioports = &setup_scc3_ioports; 282 break; 283 default: 284 printk(KERN_WARNING "Device %s is not supported!\n", pdev->name); 285 return; 286 } 287 288 pdev->dev.platform_data = fpi; 289 fpi->fs_no = fs_no; 290 291 e = (unsigned char *)&bd->bi_enetaddr; 292 for (i = 0; i < 6; i++) 293 fpi->macaddr[i] = *e++; 294 295 fpi->macaddr[5] += mac_count++; 296 297} 298 299static void mpc885ads_fixup_fec_enet_pdata(struct platform_device *pdev, 300 int idx) 301{ 302 /* This is for FEC devices only */ 303 if (!pdev || !pdev->name || (!strstr(pdev->name, "fsl-cpm-fec"))) 304 return; 305 mpc885ads_fixup_enet_pdata(pdev, fsid_fec1 + pdev->id - 1); 306} 307 308static void __init mpc885ads_fixup_scc_enet_pdata(struct platform_device *pdev, 309 int idx) 310{ 311 /* This is for SCC devices only */ 312 if (!pdev || !pdev->name || (!strstr(pdev->name, "fsl-cpm-scc"))) 313 return; 314 315 mpc885ads_fixup_enet_pdata(pdev, fsid_scc1 + pdev->id - 1); 316} 317 318static void setup_smc1_ioports(struct fs_uart_platform_info* pdata) 319{ 320 immap_t *immap = (immap_t *) IMAP_ADDR; 321 unsigned *bcsr_io; 322 unsigned int iobits = 0x000000c0; 323 324 bcsr_io = ioremap(BCSR1, sizeof(unsigned long)); 325 326 if (bcsr_io == NULL) { 327 printk(KERN_CRIT "Could not remap BCSR1\n"); 328 return; 329 } 330 clrbits32(bcsr_io,BCSR1_RS232EN_1); 331 iounmap(bcsr_io); 332 333 setbits32(&immap->im_cpm.cp_pbpar, iobits); 334 clrbits32(&immap->im_cpm.cp_pbdir, iobits); 335 clrbits16(&immap->im_cpm.cp_pbodr, iobits); 336} 337 338static void setup_smc2_ioports(struct fs_uart_platform_info* pdata) 339{ 340 immap_t *immap = (immap_t *) IMAP_ADDR; 341 unsigned *bcsr_io; 342 unsigned int iobits = 0x00000c00; 343 344 bcsr_io = ioremap(BCSR1, sizeof(unsigned long)); 345 346 if (bcsr_io == NULL) { 347 printk(KERN_CRIT "Could not remap BCSR1\n"); 348 return; 349 } 350 clrbits32(bcsr_io,BCSR1_RS232EN_2); 351 iounmap(bcsr_io); 352 353#ifndef CONFIG_SERIAL_CPM_ALT_SMC2 354 setbits32(&immap->im_cpm.cp_pbpar, iobits); 355 clrbits32(&immap->im_cpm.cp_pbdir, iobits); 356 clrbits16(&immap->im_cpm.cp_pbodr, iobits); 357#else 358 setbits16(&immap->im_ioport.iop_papar, iobits); 359 clrbits16(&immap->im_ioport.iop_padir, iobits); 360 clrbits16(&immap->im_ioport.iop_paodr, iobits); 361#endif 362} 363 364static void __init mpc885ads_fixup_uart_pdata(struct platform_device *pdev, 365 int idx) 366{ 367 bd_t *bd = (bd_t *) __res; 368 struct fs_uart_platform_info *pinfo; 369 int num = ARRAY_SIZE(mpc885_uart_pdata); 370 371 int id = fs_uart_id_smc2fsid(idx); 372 373 /* no need to alter anything if console */ 374 if ((id < num) && (!pdev->dev.platform_data)) { 375 pinfo = &mpc885_uart_pdata[id]; 376 pinfo->uart_clk = bd->bi_intfreq; 377 pdev->dev.platform_data = pinfo; 378 } 379} 380 381 382static int mpc885ads_platform_notify(struct device *dev) 383{ 384 385 static const struct platform_notify_dev_map dev_map[] = { 386 { 387 .bus_id = "fsl-cpm-fec", 388 .rtn = mpc885ads_fixup_fec_enet_pdata, 389 }, 390 { 391 .bus_id = "fsl-cpm-scc", 392 .rtn = mpc885ads_fixup_scc_enet_pdata, 393 }, 394 { 395 .bus_id = "fsl-cpm-smc:uart", 396 .rtn = mpc885ads_fixup_uart_pdata 397 }, 398 { 399 .bus_id = NULL 400 } 401 }; 402 403 platform_notify_map(dev_map,dev); 404 405 return 0; 406} 407 408int __init mpc885ads_init(void) 409{ 410 struct fs_mii_fec_platform_info* fmpi; 411 bd_t *bd = (bd_t *) __res; 412 413 printk(KERN_NOTICE "mpc885ads: Init\n"); 414 415 platform_notify = mpc885ads_platform_notify; 416 417 ppc_sys_device_initfunc(); 418 ppc_sys_device_disable_all(); 419 420 ppc_sys_device_enable(MPC8xx_CPM_FEC1); 421 422 ppc_sys_device_enable(MPC8xx_MDIO_FEC); 423 fmpi = ppc_sys_platform_devices[MPC8xx_MDIO_FEC].dev.platform_data = 424 &mpc8xx_mdio_fec_pdata; 425 426 fmpi->mii_speed = ((((bd->bi_intfreq + 4999999) / 2500000) / 2) & 0x3F) << 1; 427 428 /* No PHY interrupt line here */ 429 fmpi->irq[0xf] = SIU_IRQ7; 430 431#ifdef CONFIG_MPC8xx_SECOND_ETH_SCC3 432 ppc_sys_device_enable(MPC8xx_CPM_SCC3); 433 434#endif 435#ifdef CONFIG_MPC8xx_SECOND_ETH_FEC2 436 ppc_sys_device_enable(MPC8xx_CPM_FEC2); 437#endif 438 439#ifdef CONFIG_SERIAL_CPM_SMC1 440 ppc_sys_device_enable(MPC8xx_CPM_SMC1); 441 ppc_sys_device_setfunc(MPC8xx_CPM_SMC1, PPC_SYS_FUNC_UART); 442#endif 443 444#ifdef CONFIG_SERIAL_CPM_SMC2 445 ppc_sys_device_enable(MPC8xx_CPM_SMC2); 446 ppc_sys_device_setfunc(MPC8xx_CPM_SMC2, PPC_SYS_FUNC_UART); 447#endif 448 return 0; 449} 450 451arch_initcall(mpc885ads_init); 452 453/* 454 To prevent confusion, console selection is gross: 455 by 0 assumed SMC1 and by 1 assumed SMC2 456 */ 457struct platform_device* early_uart_get_pdev(int index) 458{ 459 bd_t *bd = (bd_t *) __res; 460 struct fs_uart_platform_info *pinfo; 461 462 struct platform_device* pdev = NULL; 463 if(index) { /*assume SMC2 here*/ 464 pdev = &ppc_sys_platform_devices[MPC8xx_CPM_SMC2]; 465 pinfo = &mpc885_uart_pdata[1]; 466 } else { /*over SMC1*/ 467 pdev = &ppc_sys_platform_devices[MPC8xx_CPM_SMC1]; 468 pinfo = &mpc885_uart_pdata[0]; 469 } 470 471 pinfo->uart_clk = bd->bi_intfreq; 472 pdev->dev.platform_data = pinfo; 473 ppc_sys_fixup_mem_resource(pdev, IMAP_ADDR); 474 return NULL; 475} 476