1/*arch/ppc/platforms/mpc866ads_setup.c 2 * 3 * Platform setup for the Freescale mpc866ads board 4 * 5 * Vitaly Bordug <vbordug@ru.mvista.com> 6 * 7 * Copyright 2005-2006 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#include <linux/phy.h> 25 26#include <asm/delay.h> 27#include <asm/io.h> 28#include <asm/machdep.h> 29#include <asm/page.h> 30#include <asm/processor.h> 31#include <asm/system.h> 32#include <asm/time.h> 33#include <asm/ppcboot.h> 34#include <asm/8xx_immap.h> 35#include <asm/commproc.h> 36#include <asm/ppc_sys.h> 37#include <asm/mpc8xx.h> 38 39extern unsigned char __res[]; 40 41static void setup_fec1_ioports(struct fs_platform_info*); 42static void setup_scc1_ioports(struct fs_platform_info*); 43static void setup_smc1_ioports(struct fs_uart_platform_info*); 44static void setup_smc2_ioports(struct fs_uart_platform_info*); 45 46static struct fs_mii_fec_platform_info mpc8xx_mdio_fec_pdata; 47 48static struct fs_mii_fec_platform_info mpc8xx_mdio_fec_pdata; 49 50static struct fs_platform_info mpc8xx_enet_pdata[] = { 51 [fsid_fec1] = { 52 .rx_ring = 128, 53 .tx_ring = 16, 54 .rx_copybreak = 240, 55 56 .use_napi = 1, 57 .napi_weight = 17, 58 59 .init_ioports = setup_fec1_ioports, 60 61 .bus_id = "0:0f", 62 .has_phy = 1, 63 }, 64 [fsid_scc1] = { 65 .rx_ring = 64, 66 .tx_ring = 8, 67 .rx_copybreak = 240, 68 .use_napi = 1, 69 .napi_weight = 17, 70 71 72 .init_ioports = setup_scc1_ioports, 73 74 .bus_id = "fixed@100:1", 75 }, 76}; 77 78static struct fs_uart_platform_info mpc866_uart_pdata[] = { 79 [fsid_smc1_uart] = { 80 .brg = 1, 81 .fs_no = fsid_smc1_uart, 82 .init_ioports = setup_smc1_ioports, 83 .tx_num_fifo = 4, 84 .tx_buf_size = 32, 85 .rx_num_fifo = 4, 86 .rx_buf_size = 32, 87 }, 88 [fsid_smc2_uart] = { 89 .brg = 2, 90 .fs_no = fsid_smc2_uart, 91 .init_ioports = setup_smc2_ioports, 92 .tx_num_fifo = 4, 93 .tx_buf_size = 32, 94 .rx_num_fifo = 4, 95 .rx_buf_size = 32, 96 }, 97}; 98 99void __init board_init(void) 100{ 101 volatile cpm8xx_t *cp = cpmp; 102 unsigned *bcsr_io; 103 104 bcsr_io = ioremap(BCSR1, sizeof(unsigned long)); 105 106 if (bcsr_io == NULL) { 107 printk(KERN_CRIT "Could not remap BCSR1\n"); 108 return; 109 } 110 111#ifdef CONFIG_SERIAL_CPM_SMC1 112 cp->cp_simode &= ~(0xe0000000 >> 17); /* brg1 */ 113 clrbits32(bcsr_io,(0x80000000 >> 7)); 114 cp->cp_smc[0].smc_smcm |= (SMCM_RX | SMCM_TX); 115 cp->cp_smc[0].smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); 116#else 117 setbits32(bcsr_io,(0x80000000 >> 7)); 118 119 cp->cp_pbpar &= ~(0x000000c0); 120 cp->cp_pbdir |= 0x000000c0; 121 cp->cp_smc[0].smc_smcmr = 0; 122 cp->cp_smc[0].smc_smce = 0; 123#endif 124 125#ifdef CONFIG_SERIAL_CPM_SMC2 126 cp->cp_simode &= ~(0xe0000000 >> 1); 127 cp->cp_simode |= (0x20000000 >> 1); /* brg2 */ 128 clrbits32(bcsr_io,(0x80000000 >> 13)); 129 cp->cp_smc[1].smc_smcm |= (SMCM_RX | SMCM_TX); 130 cp->cp_smc[1].smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); 131#else 132 clrbits32(bcsr_io,(0x80000000 >> 13)); 133 cp->cp_pbpar &= ~(0x00000c00); 134 cp->cp_pbdir |= 0x00000c00; 135 cp->cp_smc[1].smc_smcmr = 0; 136 cp->cp_smc[1].smc_smce = 0; 137#endif 138 iounmap(bcsr_io); 139} 140 141static void setup_fec1_ioports(struct fs_platform_info* pdata) 142{ 143 immap_t *immap = (immap_t *) IMAP_ADDR; 144 145 setbits16(&immap->im_ioport.iop_pdpar, 0x1fff); 146 setbits16(&immap->im_ioport.iop_pddir, 0x1fff); 147} 148 149static void setup_scc1_ioports(struct fs_platform_info* pdata) 150{ 151 immap_t *immap = (immap_t *) IMAP_ADDR; 152 unsigned *bcsr_io; 153 154 bcsr_io = ioremap(BCSR1, sizeof(unsigned long)); 155 156 if (bcsr_io == NULL) { 157 printk(KERN_CRIT "Could not remap BCSR1\n"); 158 return; 159 } 160 161 /* Enable the PHY. 162 */ 163 clrbits32(bcsr_io,BCSR1_ETHEN); 164 165 /* Configure port A pins for Txd and Rxd. 166 */ 167 /* Disable receive and transmit in case EPPC-Bug started it. 168 */ 169 setbits16(&immap->im_ioport.iop_papar, PA_ENET_RXD | PA_ENET_TXD); 170 clrbits16(&immap->im_ioport.iop_padir, PA_ENET_RXD | PA_ENET_TXD); 171 clrbits16(&immap->im_ioport.iop_paodr, PA_ENET_TXD); 172 173 /* Configure port C pins to enable CLSN and RENA. 174 */ 175 clrbits16(&immap->im_ioport.iop_pcpar, PC_ENET_CLSN | PC_ENET_RENA); 176 clrbits16(&immap->im_ioport.iop_pcdir, PC_ENET_CLSN | PC_ENET_RENA); 177 setbits16(&immap->im_ioport.iop_pcso, PC_ENET_CLSN | PC_ENET_RENA); 178 /* Configure port A for TCLK and RCLK. 179 */ 180 setbits16(&immap->im_ioport.iop_papar, PA_ENET_TCLK | PA_ENET_RCLK); 181 clrbits16(&immap->im_ioport.iop_padir, PA_ENET_TCLK | PA_ENET_RCLK); 182 clrbits32(&immap->im_cpm.cp_pbpar, PB_ENET_TENA); 183 clrbits32(&immap->im_cpm.cp_pbdir, PB_ENET_TENA); 184 185 /* Configure Serial Interface clock routing. 186 * First, clear all SCC bits to zero, then set the ones we want. 187 */ 188 clrbits32(&immap->im_cpm.cp_sicr, SICR_ENET_MASK); 189 setbits32(&immap->im_cpm.cp_sicr, SICR_ENET_CLKRT); 190 191 /* In the original SCC enet driver the following code is placed at 192 the end of the initialization */ 193 setbits32(&immap->im_cpm.cp_pbpar, PB_ENET_TENA); 194 setbits32(&immap->im_cpm.cp_pbdir, PB_ENET_TENA); 195 196} 197 198static void setup_smc1_ioports(struct fs_uart_platform_info* pdata) 199{ 200 immap_t *immap = (immap_t *) IMAP_ADDR; 201 unsigned *bcsr_io; 202 unsigned int iobits = 0x000000c0; 203 204 bcsr_io = ioremap(BCSR1, sizeof(unsigned long)); 205 206 if (bcsr_io == NULL) { 207 printk(KERN_CRIT "Could not remap BCSR1\n"); 208 return; 209 } 210 211 clrbits32(bcsr_io,BCSR1_RS232EN_1); 212 iounmap(bcsr_io); 213 214 setbits32(&immap->im_cpm.cp_pbpar, iobits); 215 clrbits32(&immap->im_cpm.cp_pbdir, iobits); 216 clrbits16(&immap->im_cpm.cp_pbodr, iobits); 217 218} 219 220static void setup_smc2_ioports(struct fs_uart_platform_info* pdata) 221{ 222 immap_t *immap = (immap_t *) IMAP_ADDR; 223 unsigned *bcsr_io; 224 unsigned int iobits = 0x00000c00; 225 226 bcsr_io = ioremap(BCSR1, sizeof(unsigned long)); 227 228 if (bcsr_io == NULL) { 229 printk(KERN_CRIT "Could not remap BCSR1\n"); 230 return; 231 } 232 233 clrbits32(bcsr_io,BCSR1_RS232EN_2); 234 235 iounmap(bcsr_io); 236 237#ifndef CONFIG_SERIAL_CPM_ALT_SMC2 238 setbits32(&immap->im_cpm.cp_pbpar, iobits); 239 clrbits32(&immap->im_cpm.cp_pbdir, iobits); 240 clrbits16(&immap->im_cpm.cp_pbodr, iobits); 241#else 242 setbits16(&immap->im_ioport.iop_papar, iobits); 243 clrbits16(&immap->im_ioport.iop_padir, iobits); 244 clrbits16(&immap->im_ioport.iop_paodr, iobits); 245#endif 246 247} 248 249static int ma_count = 0; 250 251static void mpc866ads_fixup_enet_pdata(struct platform_device *pdev, int fs_no) 252{ 253 struct fs_platform_info *fpi; 254 255 volatile cpm8xx_t *cp; 256 bd_t *bd = (bd_t *) __res; 257 char *e; 258 int i; 259 260 /* Get pointer to Communication Processor */ 261 cp = cpmp; 262 263 if(fs_no >= ARRAY_SIZE(mpc8xx_enet_pdata)) { 264 printk(KERN_ERR"No network-suitable #%d device on bus", fs_no); 265 return; 266 } 267 268 269 fpi = &mpc8xx_enet_pdata[fs_no]; 270 fpi->fs_no = fs_no; 271 pdev->dev.platform_data = fpi; 272 273 e = (unsigned char *)&bd->bi_enetaddr; 274 for (i = 0; i < 6; i++) 275 fpi->macaddr[i] = *e++; 276 277 fpi->macaddr[5] += ma_count++; 278} 279 280static void mpc866ads_fixup_fec_enet_pdata(struct platform_device *pdev, 281 int idx) 282{ 283 /* This is for FEC devices only */ 284 if (!pdev || !pdev->name || (!strstr(pdev->name, "fsl-cpm-fec"))) 285 return; 286 mpc866ads_fixup_enet_pdata(pdev, fsid_fec1 + pdev->id - 1); 287} 288 289static void mpc866ads_fixup_scc_enet_pdata(struct platform_device *pdev, 290 int idx) 291{ 292 /* This is for SCC devices only */ 293 if (!pdev || !pdev->name || (!strstr(pdev->name, "fsl-cpm-scc"))) 294 return; 295 296 mpc866ads_fixup_enet_pdata(pdev, fsid_scc1 + pdev->id - 1); 297} 298 299static void __init mpc866ads_fixup_uart_pdata(struct platform_device *pdev, 300 int idx) 301{ 302 bd_t *bd = (bd_t *) __res; 303 struct fs_uart_platform_info *pinfo; 304 int num = ARRAY_SIZE(mpc866_uart_pdata); 305 306 int id = fs_uart_id_smc2fsid(idx); 307 308 /* no need to alter anything if console */ 309 if ((id < num) && (!pdev->dev.platform_data)) { 310 pinfo = &mpc866_uart_pdata[id]; 311 pinfo->uart_clk = bd->bi_intfreq; 312 pdev->dev.platform_data = pinfo; 313 } 314} 315 316static int mpc866ads_platform_notify(struct device *dev) 317{ 318 static const struct platform_notify_dev_map dev_map[] = { 319 { 320 .bus_id = "fsl-cpm-fec", 321 .rtn = mpc866ads_fixup_fec_enet_pdata, 322 }, 323 { 324 .bus_id = "fsl-cpm-scc", 325 .rtn = mpc866ads_fixup_scc_enet_pdata, 326 }, 327 { 328 .bus_id = "fsl-cpm-smc:uart", 329 .rtn = mpc866ads_fixup_uart_pdata 330 }, 331 { 332 .bus_id = NULL 333 } 334 }; 335 336 platform_notify_map(dev_map,dev); 337 338 return 0; 339} 340 341int __init mpc866ads_init(void) 342{ 343 bd_t *bd = (bd_t *) __res; 344 struct fs_mii_fec_platform_info* fmpi; 345 346 printk(KERN_NOTICE "mpc866ads: Init\n"); 347 348 platform_notify = mpc866ads_platform_notify; 349 350 ppc_sys_device_initfunc(); 351 ppc_sys_device_disable_all(); 352 353#ifdef CONFIG_MPC8xx_SECOND_ETH_SCC1 354 ppc_sys_device_enable(MPC8xx_CPM_SCC1); 355#endif 356 ppc_sys_device_enable(MPC8xx_CPM_FEC1); 357 358 ppc_sys_device_enable(MPC8xx_MDIO_FEC); 359 360 fmpi = ppc_sys_platform_devices[MPC8xx_MDIO_FEC].dev.platform_data = 361 &mpc8xx_mdio_fec_pdata; 362 363 fmpi->mii_speed = ((((bd->bi_intfreq + 4999999) / 2500000) / 2) & 0x3F) << 1; 364 /* No PHY interrupt line here */ 365 fmpi->irq[0xf] = PHY_POLL; 366 367/* Since either of the uarts could be used as console, they need to ready */ 368#ifdef CONFIG_SERIAL_CPM_SMC1 369 ppc_sys_device_enable(MPC8xx_CPM_SMC1); 370 ppc_sys_device_setfunc(MPC8xx_CPM_SMC1, PPC_SYS_FUNC_UART); 371#endif 372 373#ifdef CONFIG_SERIAL_CPM_SMC2 374 ppc_sys_device_enable(MPC8xx_CPM_SMC2); 375 ppc_sys_device_setfunc(MPC8xx_CPM_SMC2, PPC_SYS_FUNC_UART); 376#endif 377 ppc_sys_device_enable(MPC8xx_MDIO_FEC); 378 379 fmpi = ppc_sys_platform_devices[MPC8xx_MDIO_FEC].dev.platform_data = 380 &mpc8xx_mdio_fec_pdata; 381 382 fmpi->mii_speed = ((((bd->bi_intfreq + 4999999) / 2500000) / 2) & 0x3F) << 1; 383 /* No PHY interrupt line here */ 384 fmpi->irq[0xf] = PHY_POLL; 385 386 return 0; 387} 388 389/* 390 To prevent confusion, console selection is gross: 391 by 0 assumed SMC1 and by 1 assumed SMC2 392 */ 393struct platform_device* early_uart_get_pdev(int index) 394{ 395 bd_t *bd = (bd_t *) __res; 396 struct fs_uart_platform_info *pinfo; 397 398 struct platform_device* pdev = NULL; 399 if(index) { /*assume SMC2 here*/ 400 pdev = &ppc_sys_platform_devices[MPC8xx_CPM_SMC2]; 401 pinfo = &mpc866_uart_pdata[1]; 402 } else { /*over SMC1*/ 403 pdev = &ppc_sys_platform_devices[MPC8xx_CPM_SMC1]; 404 pinfo = &mpc866_uart_pdata[0]; 405 } 406 407 pinfo->uart_clk = bd->bi_intfreq; 408 pdev->dev.platform_data = pinfo; 409 ppc_sys_fixup_mem_resource(pdev, IMAP_ADDR); 410 return NULL; 411} 412 413arch_initcall(mpc866ads_init); 414