nettel.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /***************************************************************************/
  2. /*
  3. * nettel.c -- startup code support for the NETtel boards
  4. *
  5. * Copyright (C) 2009, Greg Ungerer (gerg@snapgear.com)
  6. */
  7. /***************************************************************************/
  8. #include <linux/kernel.h>
  9. #include <linux/param.h>
  10. #include <linux/init.h>
  11. #include <linux/io.h>
  12. #include <linux/platform_device.h>
  13. #include <asm/coldfire.h>
  14. #include <asm/mcfsim.h>
  15. #include <asm/nettel.h>
  16. /***************************************************************************/
  17. /*
  18. * Define the IO and interrupt resources of the 2 SMC9196 interfaces.
  19. */
  20. #define NETTEL_SMC0_ADDR 0x30600300
  21. #define NETTEL_SMC0_IRQ 29
  22. #define NETTEL_SMC1_ADDR 0x30600000
  23. #define NETTEL_SMC1_IRQ 27
  24. /*
  25. * We need some access into the SMC9196 registers. Define those registers
  26. * we will need here (including the smc91x.h doesn't seem to give us these
  27. * in a simple form).
  28. */
  29. #define SMC91xx_BANKSELECT 14
  30. #define SMC91xx_BASEADDR 2
  31. #define SMC91xx_BASEMAC 4
  32. /***************************************************************************/
  33. static struct resource nettel_smc91x_0_resources[] = {
  34. {
  35. .start = NETTEL_SMC0_ADDR,
  36. .end = NETTEL_SMC0_ADDR + 0x20,
  37. .flags = IORESOURCE_MEM,
  38. },
  39. {
  40. .start = NETTEL_SMC0_IRQ,
  41. .end = NETTEL_SMC0_IRQ,
  42. .flags = IORESOURCE_IRQ,
  43. },
  44. };
  45. static struct resource nettel_smc91x_1_resources[] = {
  46. {
  47. .start = NETTEL_SMC1_ADDR,
  48. .end = NETTEL_SMC1_ADDR + 0x20,
  49. .flags = IORESOURCE_MEM,
  50. },
  51. {
  52. .start = NETTEL_SMC1_IRQ,
  53. .end = NETTEL_SMC1_IRQ,
  54. .flags = IORESOURCE_IRQ,
  55. },
  56. };
  57. static struct platform_device nettel_smc91x[] = {
  58. {
  59. .name = "smc91x",
  60. .id = 0,
  61. .num_resources = ARRAY_SIZE(nettel_smc91x_0_resources),
  62. .resource = nettel_smc91x_0_resources,
  63. },
  64. {
  65. .name = "smc91x",
  66. .id = 1,
  67. .num_resources = ARRAY_SIZE(nettel_smc91x_1_resources),
  68. .resource = nettel_smc91x_1_resources,
  69. },
  70. };
  71. static struct platform_device *nettel_devices[] __initdata = {
  72. &nettel_smc91x[0],
  73. &nettel_smc91x[1],
  74. };
  75. /***************************************************************************/
  76. static u8 nettel_macdefault[] __initdata = {
  77. 0x00, 0xd0, 0xcf, 0x00, 0x00, 0x01,
  78. };
  79. /*
  80. * Set flash contained MAC address into SMC9196 core. Make sure the flash
  81. * MAC address is sane, and not an empty flash. If no good use the Moreton
  82. * Bay default MAC address instead.
  83. */
  84. static void __init nettel_smc91x_setmac(unsigned int ioaddr, unsigned int flashaddr)
  85. {
  86. u16 *macp;
  87. macp = (u16 *) flashaddr;
  88. if ((macp[0] == 0xffff) && (macp[1] == 0xffff) && (macp[2] == 0xffff))
  89. macp = (u16 *) &nettel_macdefault[0];
  90. writew(1, NETTEL_SMC0_ADDR + SMC91xx_BANKSELECT);
  91. writew(macp[0], ioaddr + SMC91xx_BASEMAC);
  92. writew(macp[1], ioaddr + SMC91xx_BASEMAC + 2);
  93. writew(macp[2], ioaddr + SMC91xx_BASEMAC + 4);
  94. }
  95. /***************************************************************************/
  96. /*
  97. * Re-map the address space of at least one of the SMC ethernet
  98. * parts. Both parts power up decoding the same address, so we
  99. * need to move one of them first, before doing anything else.
  100. */
  101. static void __init nettel_smc91x_init(void)
  102. {
  103. writew(0x00ec, MCFSIM_PADDR);
  104. mcf_setppdata(0, 0x0080);
  105. writew(1, NETTEL_SMC0_ADDR + SMC91xx_BANKSELECT);
  106. writew(0x0067, NETTEL_SMC0_ADDR + SMC91xx_BASEADDR);
  107. mcf_setppdata(0x0080, 0);
  108. /* Set correct chip select timing for SMC9196 accesses */
  109. writew(0x1180, MCFSIM_CSCR3);
  110. /* Set the SMC interrupts to be auto-vectored */
  111. mcf_autovector(NETTEL_SMC0_IRQ);
  112. mcf_autovector(NETTEL_SMC1_IRQ);
  113. /* Set MAC addresses from flash for both interfaces */
  114. nettel_smc91x_setmac(NETTEL_SMC0_ADDR, 0xf0006000);
  115. nettel_smc91x_setmac(NETTEL_SMC1_ADDR, 0xf0006006);
  116. }
  117. /***************************************************************************/
  118. static int __init init_nettel(void)
  119. {
  120. nettel_smc91x_init();
  121. platform_add_devices(nettel_devices, ARRAY_SIZE(nettel_devices));
  122. return 0;
  123. }
  124. arch_initcall(init_nettel);
  125. /***************************************************************************/