mpc866ads_setup.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  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. #include <linux/config.h>
  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. #include <linux/fs_enet_pd.h>
  21. #include <linux/mii.h>
  22. #include <asm/delay.h>
  23. #include <asm/io.h>
  24. #include <asm/machdep.h>
  25. #include <asm/page.h>
  26. #include <asm/processor.h>
  27. #include <asm/system.h>
  28. #include <asm/time.h>
  29. #include <asm/ppcboot.h>
  30. #include <asm/8xx_immap.h>
  31. #include <asm/commproc.h>
  32. #include <asm/ppc_sys.h>
  33. #include <asm/mpc8xx.h>
  34. extern unsigned char __res[];
  35. static struct fs_mii_bus_info fec_mii_bus_info = {
  36. .method = fsmii_fec,
  37. .id = 0,
  38. };
  39. static struct fs_mii_bus_info scc_mii_bus_info = {
  40. .method = fsmii_fixed,
  41. .id = 0,
  42. .i.fixed.speed = 10,
  43. .i.fixed.duplex = 0,
  44. };
  45. static struct fs_platform_info mpc8xx_fec_pdata[] = {
  46. {
  47. .rx_ring = 128,
  48. .tx_ring = 16,
  49. .rx_copybreak = 240,
  50. .use_napi = 1,
  51. .napi_weight = 17,
  52. .phy_addr = 15,
  53. .phy_irq = -1,
  54. .use_rmii = 0,
  55. .bus_info = &fec_mii_bus_info,
  56. }
  57. };
  58. static struct fs_platform_info mpc8xx_scc_pdata = {
  59. .rx_ring = 64,
  60. .tx_ring = 8,
  61. .rx_copybreak = 240,
  62. .use_napi = 1,
  63. .napi_weight = 17,
  64. .phy_addr = -1,
  65. .phy_irq = -1,
  66. .bus_info = &scc_mii_bus_info,
  67. };
  68. void __init board_init(void)
  69. {
  70. volatile cpm8xx_t *cp = cpmp;
  71. unsigned *bcsr_io;
  72. bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
  73. if (bcsr_io == NULL) {
  74. printk(KERN_CRIT "Could not remap BCSR1\n");
  75. return;
  76. }
  77. #ifdef CONFIG_SERIAL_CPM_SMC1
  78. cp->cp_simode &= ~(0xe0000000 >> 17); /* brg1 */
  79. clrbits32(bcsr_io,(0x80000000 >> 7));
  80. #else
  81. setbits32(bcsr_io,(0x80000000 >> 7));
  82. cp->cp_pbpar &= ~(0x000000c0);
  83. cp->cp_pbdir |= 0x000000c0;
  84. cp->cp_smc[0].smc_smcmr = 0;
  85. cp->cp_smc[0].smc_smce = 0;
  86. #endif
  87. #ifdef CONFIG_SERIAL_CPM_SMC2
  88. cp->cp_simode &= ~(0xe0000000 >> 1);
  89. cp->cp_simode |= (0x20000000 >> 1); /* brg2 */
  90. clrbits32(bcsr_io,(0x80000000 >> 13));
  91. #else
  92. clrbits32(bcsr_io,(0x80000000 >> 13));
  93. cp->cp_pbpar &= ~(0x00000c00);
  94. cp->cp_pbdir |= 0x00000c00;
  95. cp->cp_smc[1].smc_smcmr = 0;
  96. cp->cp_smc[1].smc_smce = 0;
  97. #endif
  98. iounmap(bcsr_io);
  99. }
  100. static void setup_fec1_ioports(void)
  101. {
  102. immap_t *immap = (immap_t *) IMAP_ADDR;
  103. setbits16(&immap->im_ioport.iop_pdpar, 0x1fff);
  104. setbits16(&immap->im_ioport.iop_pddir, 0x1fff);
  105. }
  106. static void setup_scc1_ioports(void)
  107. {
  108. immap_t *immap = (immap_t *) IMAP_ADDR;
  109. unsigned *bcsr_io;
  110. bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
  111. if (bcsr_io == NULL) {
  112. printk(KERN_CRIT "Could not remap BCSR1\n");
  113. return;
  114. }
  115. /* Enable the PHY.
  116. */
  117. clrbits32(bcsr_io,BCSR1_ETHEN);
  118. /* Configure port A pins for Txd and Rxd.
  119. */
  120. /* Disable receive and transmit in case EPPC-Bug started it.
  121. */
  122. setbits16(&immap->im_ioport.iop_papar, PA_ENET_RXD | PA_ENET_TXD);
  123. clrbits16(&immap->im_ioport.iop_padir, PA_ENET_RXD | PA_ENET_TXD);
  124. clrbits16(&immap->im_ioport.iop_paodr, PA_ENET_TXD);
  125. /* Configure port C pins to enable CLSN and RENA.
  126. */
  127. clrbits16(&immap->im_ioport.iop_pcpar, PC_ENET_CLSN | PC_ENET_RENA);
  128. clrbits16(&immap->im_ioport.iop_pcdir, PC_ENET_CLSN | PC_ENET_RENA);
  129. setbits16(&immap->im_ioport.iop_pcso, PC_ENET_CLSN | PC_ENET_RENA);
  130. /* Configure port A for TCLK and RCLK.
  131. */
  132. setbits16(&immap->im_ioport.iop_papar, PA_ENET_TCLK | PA_ENET_RCLK);
  133. clrbits16(&immap->im_ioport.iop_padir, PA_ENET_TCLK | PA_ENET_RCLK);
  134. clrbits32(&immap->im_cpm.cp_pbpar, PB_ENET_TENA);
  135. clrbits32(&immap->im_cpm.cp_pbdir, PB_ENET_TENA);
  136. /* Configure Serial Interface clock routing.
  137. * First, clear all SCC bits to zero, then set the ones we want.
  138. */
  139. clrbits32(&immap->im_cpm.cp_sicr, SICR_ENET_MASK);
  140. setbits32(&immap->im_cpm.cp_sicr, SICR_ENET_CLKRT);
  141. /* In the original SCC enet driver the following code is placed at
  142. the end of the initialization */
  143. setbits32(&immap->im_cpm.cp_pbpar, PB_ENET_TENA);
  144. setbits32(&immap->im_cpm.cp_pbdir, PB_ENET_TENA);
  145. }
  146. static void mpc866ads_fixup_enet_pdata(struct platform_device *pdev, int fs_no)
  147. {
  148. struct fs_platform_info *fpi = pdev->dev.platform_data;
  149. volatile cpm8xx_t *cp;
  150. bd_t *bd = (bd_t *) __res;
  151. char *e;
  152. int i;
  153. /* Get pointer to Communication Processor */
  154. cp = cpmp;
  155. switch (fs_no) {
  156. case fsid_fec1:
  157. fpi = &mpc8xx_fec_pdata[0];
  158. fpi->init_ioports = &setup_fec1_ioports;
  159. break;
  160. case fsid_scc1:
  161. fpi = &mpc8xx_scc_pdata;
  162. fpi->init_ioports = &setup_scc1_ioports;
  163. break;
  164. default:
  165. printk(KERN_WARNING"Device %s is not supported!\n", pdev->name);
  166. return;
  167. }
  168. pdev->dev.platform_data = fpi;
  169. fpi->fs_no = fs_no;
  170. e = (unsigned char *)&bd->bi_enetaddr;
  171. for (i = 0; i < 6; i++)
  172. fpi->macaddr[i] = *e++;
  173. fpi->macaddr[5 - pdev->id]++;
  174. }
  175. static void mpc866ads_fixup_fec_enet_pdata(struct platform_device *pdev,
  176. int idx)
  177. {
  178. /* This is for FEC devices only */
  179. if (!pdev || !pdev->name || (!strstr(pdev->name, "fsl-cpm-fec")))
  180. return;
  181. mpc866ads_fixup_enet_pdata(pdev, fsid_fec1 + pdev->id - 1);
  182. }
  183. static void mpc866ads_fixup_scc_enet_pdata(struct platform_device *pdev,
  184. int idx)
  185. {
  186. /* This is for SCC devices only */
  187. if (!pdev || !pdev->name || (!strstr(pdev->name, "fsl-cpm-scc")))
  188. return;
  189. mpc866ads_fixup_enet_pdata(pdev, fsid_scc1 + pdev->id - 1);
  190. }
  191. static int mpc866ads_platform_notify(struct device *dev)
  192. {
  193. static const struct platform_notify_dev_map dev_map[] = {
  194. {
  195. .bus_id = "fsl-cpm-fec",
  196. .rtn = mpc866ads_fixup_fec_enet_pdata,
  197. },
  198. {
  199. .bus_id = "fsl-cpm-scc",
  200. .rtn = mpc866ads_fixup_scc_enet_pdata,
  201. },
  202. {
  203. .bus_id = NULL
  204. }
  205. };
  206. platform_notify_map(dev_map,dev);
  207. return 0;
  208. }
  209. int __init mpc866ads_init(void)
  210. {
  211. printk(KERN_NOTICE "mpc866ads: Init\n");
  212. platform_notify = mpc866ads_platform_notify;
  213. ppc_sys_device_initfunc();
  214. ppc_sys_device_disable_all();
  215. #ifdef MPC8xx_SECOND_ETH_SCC1
  216. ppc_sys_device_enable(MPC8xx_CPM_SCC1);
  217. #endif
  218. ppc_sys_device_enable(MPC8xx_CPM_FEC1);
  219. return 0;
  220. }
  221. arch_initcall(mpc866ads_init);