mpc866ads_setup.c 10.0 KB

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